最近我一直在尝试优化我的表,主要是因为我通过学校的一些课程学到了更多关于数据库设计的知识。我也选择这样做,因为我在某些查询上遇到了很多超时,最近发现这确实是我的数据库设计错误。
所以基本上,我将在这张表上执行 SELECT、UPDATE、INSERT 和 DELETE。
这是我当前的数据库架构:
-- ----------------------------
-- 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;
如您所见,我几乎总是引用 slot_id、type 和 master_id 字段。我想知道如果我将 slot_id 和 type 字段设置为索引字段,它将如何影响我的整体数据操作性能?会受到正面的影响,还是负面的影响?
请给我一些建议(C#代码除外,我稍后会修复它!)