索引表与重复MySQL / SQL Server具有数百万条记录

时间:2010-02-05 13:16:30

标签: sql mysql sql-server indexing

我需要帮助MySQL中的索引。 我在MySQL中有一个表,其中包含以下行:

ID Store_ID Feature_ID Order_ID Viewed_Date Deal_ID IsTrial
ID是自动生成的。 Store_ID从1 - 8开始.Feit_ID从1开始 - 让我们说100.查看日期是插入数据的日期和时间。 IsTrial是0或1.
您可以忽略此讨论中的Order_ID和Deal_ID。

表中有数百万个数据,我们有一个报告后端,需要查看某个特定商店ID和特定功能的特定时间段或整体中的视图数量。

查询采用以下形式:

select count(viewed_date) 
from theTable
where viewed_date between '2009-12-01' and '2010-12-31'
and store_id = '2' 
and feature_id = '12'
and Istrial = 0

在SQL Server中,您可以使用筛选索引用于Istrial。 MySQL中有类似的东西吗?此外,Store_ID和Feature_ID有很多重复数据。我使用Store_ID和Feature_ID创建了一个索引。虽然这似乎缩短了搜索周期,但我需要比这更好的改进。现在我有超过400万行。要搜索上面的特定查询,它会查看350万行,以便为我提供500k行的计数。

PS。我忘了在查询中添加view_date过滤器。现在我做到了这一点。

5 个答案:

答案 0 :(得分:0)

如果您需要在MySQL中专门优化此查询,为什么不在Store_ID和Feature_ID的现有索引的末尾添加istrial。这将完全索引WHERE子句,并且如果表是MyISAM,则能够从索引的基数摘要中获取COUNT。利用当前索引的所有现有查询也将保持不变。

编辑:另外,我不确定你为什么要COUNT(viewed_date)而不是COUNT(*)viewed_date是否为空?如果没有,您可以使用COUNT(*),如果您将其与我的其他建议结合使用,则无需转到.MYD文件。

答案 1 :(得分:0)

您可以将索引扩展为包含Store_ID,Feature_ID和IsTrial。在性能方面,你不会比这更好。

答案 2 :(得分:0)

我的第一个想法是(feature_id,store_id,istrial)上的索引,因为feature_id似乎是具有最高Shannon熵的列。但是在不知道feature_id的统计数据的情况下,我不确定。也许你最好创建两个索引,(store_id,feature_id,istrial)是另一个,让优化器对它进行排序。使用所有三列还具有以下优势:数据库能够仅从索引中回答您的查询,这也可以提高性能。

但是如果你的列都没有足够的选择性足以提高索引性能,你可能不得不通过使用INSERT / UPDATE触发器填充第二个表(feature_id,store_id,istrial,view_count)来求解非规范化。这会减慢插入和更新,当然......

答案 3 :(得分:0)

您可能想要考虑水平拆分该表。您可以运行将每个store_id放在单独的表中的夜间作业。或者看看feature_id,是的,它是很多表,但如果你不需要实时数据。这是我要走的路。

答案 4 :(得分:0)

我在解决这个问题时找到的最好方法是跳过DTA的建议,并按照以下方式自行完成:

  • 使用Profiler根据CPU使用率(可能阻塞查询)查找成本最高的查询,并根据这些查询将索引应用于表。如果可以更改查询执行计划以减少读取,写入和总体执行时间,那么首先执行此操作。如果不是,在这种情况下查询就是这样,那么应用聚簇/非聚集索引组合以最佳地适合。这取决于现有表索引的性质,参与索引的列的总字节数等等。
  • 在SSMS中运行查询以查找执行频率最高的查询,并执行与上述相同的操作。
  • 创建碎片整理计划,以便重新组织或重建索引,具体取决于它们的碎片程度。

我很确定其他人可以提出好主意。这样做给了我很好的结果。我希望有人可以使用这个帮助。我认为DTA在索引方面并没有真正使事情变得更快,因为你真的需要了解它将要创建的所有索引。对于遭受重创的数据库来说更是如此。