Mysql SQL:数据操作和索引

Mysql SQL:数据操作和索引,mysql,database-design,indexing,Mysql,Database Design,Indexing,最近我一直在尝试优化我的表,主要是因为我通过学校的一些课程学到了更多关于数据库设计的知识。我之所以选择这样做,也是因为我在一些查询中遇到了很多超时,最近我发现这确实是我糟糕的数据库设计 所以基本上,我将在这个表上进行选择、更新、插入和删除 以下是我当前的数据库架构: -- ---------------------------- -- Table structure for `characters_items` -- ---------------------------- DROP TABLE

最近我一直在尝试优化我的表,主要是因为我通过学校的一些课程学到了更多关于数据库设计的知识。我之所以选择这样做,也是因为我在一些查询中遇到了很多超时,最近我发现这确实是我糟糕的数据库设计

所以基本上,我将在这个表上进行选择、更新、插入和删除

以下是我当前的数据库架构:

-- ----------------------------
-- Table structure for `characters_items`
-- ----------------------------
DROP TABLE IF EXISTS `characters_items`;
CREATE TABLE `characters_items` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `master_id` int(10) unsigned NOT NULL DEFAULT '0',
  `item_id` smallint(6) NOT NULL,
  `amount` int(11) NOT NULL,
  `slot_id` smallint(9) NOT NULL DEFAULT '0',
  `type` tinyint(4) NOT NULL DEFAULT '0',
  `extra_data` text,
  PRIMARY KEY (`id`),
  KEY `master_id` (`master_id`),
  CONSTRAINT `characters_items_ibfk_1` FOREIGN KEY (`master_id`) REFERENCES `characters` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=904 DEFAULT CHARSET=latin1;
在我的程序中,我将处理大量数据(一次最多500行,正如您可以看到的,这是一个用于所有字符项的表)

我还了解到,如果您正在进行数据操作,索引值会降低查询速度

以下是我将使用的一些查询:

            StringBuilder query = new StringBuilder();

            client.ClearParameters();
            client.AddParameter("master_id", this.owner.MasterId);
            client.AddParameter("type", (byte)CharacterItemType.Bank);
            client.AddParameter("capacity", this.Capacity);

            // Grab the original items.
            DataRow[] data = client.ReadDataTable("SELECT item_id,amount,slot_id FROM characters_items WHERE master_id=@master_id AND type=@type LIMIT @capacity").Select();
            Item[] originalItems = new Item[this.Capacity];
            if (data != null && data.Length > 0)
            {
                for (short i = 0; i < data.Length; i++)
                {
                    DataRow row = data[i];

                    short id = (short)row[0];
                    int count = (int)row[1];
                    short slotId = (short)row[2];

                    originalItems[slotId] = new Item(id, count);
                }
            }

            // Now we compare the items to see if anything has been changed.
            Item[] items = this.ToArray();
            for (short i = 0; i < items.Length; i++)
            {
                Item item = items[i];
                Item original = originalItems[i];

                // item was added.
                if (item != null && original == null)
                {
                    query.Append("INSERT INTO characters_items (master_id,item_id,amount,slot_id,type,extra_data) ");
                    query.Append("VALUES (");
                    query.Append(this.owner.MasterId);
                    query.Append(",");
                    query.Append(item.Id);
                    query.Append(",");
                    query.Append(item.Count);
                    query.Append(",");
                    query.Append(i);
                    query.Append(",");
                    query.Append((byte)CharacterItemType.Bank);

                    string extraData = item.SerializeExtraData();
                    if (extraData != null)
                    {
                        query.Append(",'");
                        query.Append(extraData);
                        query.Append("'");
                    }
                    else
                    {
                        query.Append(",null");
                    }

                    query.Append(");");
                }
                // item was deleted.
                else if (item == null && original != null)
                {
                    query.Append("DELETE FROM characters_items WHERE slot_id=");
                    query.Append(i);
                    query.Append(" AND master_id=");
                    query.Append(this.owner.MasterId);
                    query.Append(" AND type=");
                    query.Append((byte)CharacterItemType.Inventory);
                    query.Append(" LIMIT 1;");
                }
                // item was modified.
                else if (item != null && original != null)
                {
                    if (item.Id != original.Id || item.Count != original.Count)
                    {
                        query.Append("UPDATE characters_items SET item_id=");
                        query.Append(item.Id);
                        query.Append(",amount=");
                        query.Append(item.Count);

                        string extraData = item.SerializeExtraData();
                        if (extraData != null)
                        {
                            query.Append(",extra_data='");
                            query.Append(extraData);
                            query.Append("'");
                        }
                        else
                        {
                            query.Append(",extra_data=null");
                        }

                        query.Append(" WHERE master_id=@master_id AND type=@type AND slot_id=");
                        query.Append(i);
                        query.Append(";");
                    }
                }
            }

            // If a query was actually built, we will execute it.
            if (query.Length > 0)
            {
                client.SetConnectionTimeout(60);
                client.ExecuteUpdate(query.ToString());
                return true;
            }
        }
        catch (Exception ex)
        {
            Program.Logger.PrintException(ex);
        }
        return false;
StringBuilder查询=新建StringBuilder();
client.ClearParameters();
client.AddParameter(“master_id”,this.owner.MasterId);
AddParameter(“type”,(byte)CharacterItemType.Bank);
client.AddParameter(“容量”,this.capacity);
//抓取原始物品。
DataRow[]data=client.ReadDataTable(“从字符项中选择项目项号、金额、插槽号,其中主项号=@master\u号,类型=@type-LIMIT@capacity”)。选择();
Item[]originalItems=新项[this.Capacity];
if(data!=null&&data.Length>0)
{
对于(短i=0;i0)
{
客户端设置连接超时(60);
client.ExecuteUpdate(query.ToString());
返回true;
}
}
捕获(例外情况除外)
{
Program.Logger.PrintException(ex);
}
返回false;
如您所见,我几乎总是引用slot\u id、type和master\u id字段。我想知道如果我将slot_id和type字段设置为索引字段,它将如何影响我的总体数据操作性能?会以积极的方式受到影响,还是会以消极的方式受到影响


请给我一些建议(除了C#代码,我稍后会解决!)

如果IDEX对select语句的where子句具有高选择性,它们将加快您的select

检查最常运行的select语句,然后对where子句中使用的字段编制索引。 如果使用通配符(特别是像“%something%”这样的东西),索引将不太有用

我不记得MySQL是否能在这方面做得很好
ALTER TABLE characters_items
ADD KEY characters_items_IX1 (master_id, item_id, slot_id);
ALTER TABLE characters_items
ADD KEY characters_items_IX1 (master_id, item_id, slot_id, type, amount);
ADD KEY characters_items_IX1 (master_id, item_id, slot_id, type, amount);