2010-01-15 41 views
3

我有一个包含900万条记录的mysql表,它没有设置任何索引。我需要根据公共ID将其加入到另一个表中。我要添加一个索引到这个ID,但我也有其他字段在选择其中子句。什么时候在已连接的表上添加索引

我应该添加一个索引到其中子句中的所有字段吗?

选择子句中的字段?我应该为所有字段创建一个索引还是为每个字段创建一个索引?

更新 - 增加了表格和查询

下面是该查询 - 我需要在项目基础上,商店名称和店铺ID(店铺名称来获得销售,项目名称和项目ID的数量并通过自己的ID不是唯一的)

SELECT COUNT(*) as salescount, items.itemName, CONCAT(items.ID, items.productcode) as itemId 
FROM items JOIN sales ON items.itemId = sales.itemId WHERE items.StoreName = ? 
AND sales.storeID = ? GROUP BY items.ItemId ORDER BY salescount DESC LIMIT 10; 

这里是销售表:

+----------------+------------------------------+------+-----+---------+-------+ 
| Field   | Type       | Null | Key | Default | Extra | 
+----------------+------------------------------+------+-----+---------+-------+ 
| StoreId  | bigint(20) unsigned   | NO |  | NULL |  | 
| ItemId   | bigint(20) unsigned   | NO |  | NULL |  | 
+----------------+------------------------------+------+-----+---------+-------+ 

和项目表:

+--------------------+------------------------------+------+-----+---------+-------+ 
| Field    | Type       | Null | Key | Default | Extra | 
+--------------------+------------------------------+------+-----+---------+-------+ 
| ItemId    | bigint(20) unsigned   | NO | PRI | NULL |  | 
| ProductCode  | bigint(20) unsigned   | NO |  | NULL |  | 
| ItemName   | varchar(100)     | NO |  | NULL |  | 
| StoreName   | varchar(100)     | NO | PRI | NULL |  | 
+--------------------+------------------------------+------+-----+---------+-------+ 

回答

4

您应该指数将在WHERE子句和在WHEREJOIN条款的驱动表中搜索中的领先表中的所有领域。

制作索引覆盖查询(包括SELECTORDER BY条款)使用也将帮助所有领域,因为没有表查找将需要。

只要在这里发布您的查询,我可能会告诉你如何索引表。

更新:

您的查询将与1最多返回1行作为一个COUNT(*)

这将选择与给定StoreID销售(这是PRIMARY KEY),并加入项目销售的itemId并给出StoreName(这个组合也是PRIMARY KEY)。

此连接成功(返回1行)或失败(不返回任何行)。如果成功,COUNT(*)将是1

如果它真的是你想要的,那么你的表格被索引很好。

但是,在我看来,您的表格设计稍微复杂一点,而您在复制字段定义时错过了一些字段。

更新2:

  1. 创建于sales (storeId, itemId)

  2. 一个综合指数确保你在itemsPRIMARY KEY被定义为(StoreName, ItemId)(按顺序)。

    如果将PK定义为(ItemID, StoreName),则在items (StoreName, ItemID)上创建索引。

+2

这个答案似乎一般我 - 你知道,'WHERE姓氏LIKE '%史密斯%''或'WHERE SUBSTRING(ID,2,1)将不利于=“2''从索引的所有。 – RedFilter 2010-01-15 18:59:36

+0

鉴于缺乏信息,很难给出更具体的答案。但即使有这些条件,查询仍然可以从索引中受益。如果表格记录很大,则可以使用完整索引扫描来搜索记录,而不是全表扫描。但是MySQL不支持后期查找,因此可能需要重写查询。 – Quassnoi 2010-01-15 19:11:54

+0

'@ Orbman':第一个查询,假设'Smith'是大写的,将受益于'FULLTEXT'索引,被重写为'MATCH(LastName)AGAINST('+ Smith *'IN BOOLEAN MODE)'。当然,这将在'McSmiths'和类似的姓氏上失败:) – Quassnoi 2010-01-15 19:15:57

0

索引是很好的 - 当以正确的形式使用时。请记住,索引必须编入索引。

将您的索引集中在主键,共享键以及需要大量常见数据比较的字段上,例如文字字段和日期范围。

正确使用索引时效果很好,但索引并不能解决所有问题。即使索引良好的桌子也可能会因为一个错误的查询和手腕的轻弹而屈服。

1

是的,你确实应该有索引,但它们应该适合你的所有查询。如果没有在数据库中好好搜索一下,就很难确切地推荐要配置哪些索引。

9百万行就足够了,索引会产生很大的变化 - 但不会太大,以至于你无法修补一点。一个粗略的解决方案是创建物品(storeid),物品(itemid,店铺名称),物品(商店名称,itemid),销售(itemid),销售(storeid),销售(itemid,storeid)和销售额(storeid,itemid)然后删除没有被使用的索引。

C.

相关问题