0

任何人都可以帮助我如何创建索引,以便我的查询能够顺利执行。

目前,我有以下查询返回 8k+ 或记录。但它需要 2 秒或更长时间才能完成。目前tblproduction的记录是1600万+

SELECT COUNT(fldglobalid) AS PackagesDone
  FROM tblproduction
 WHERE fldemployeeno = 'APD100401'
   AND fldstarttime BETWEEN '2013-08-14 07:18:06' AND '2013-08-14 16:01:58'
   AND fldshift = 'B'
   AND fldprojectgroup = 'FTO'
   AND fldGlobalID <> 0;

我的当前索引低于但它仍然查询执行时间更长

Index_1
  fldEmployeeNo
  fldStartTime

Index_2
  fldEmployeeNo
  fldTask
  fldTaskStatus

Index_3
  fldGlobalId
  fldProjectGroup

Index_4
  fldGlobalId

我已经使用 FORCE_Index 使用了所有这些索引,但查询的执行时间仍然更长。

请指教,谢谢!

4

2 回答 2

2

这开始作为评论戈登林诺夫的回答,但变得太长了。

It would be better to include fldGlobalId in the index as well- 不,不会 - 这对性能有反作用 - 它不会提高检索数据的速度(查询不用于不等式),但会导致更频繁的索引更新,从而增加索引碎片(因此可能会恶化SELECT 的性能)并降低了插入和更新的性能。

理想情况下,您应该设计您的架构以优化所有查询 - 这是一项相当大的任务,但因为您只提供了一个......

就目前而言,查询将仅使用单个索引进行解析,因此该索引应包括在查询中具有谓词的所有字段,但不匹配项(即 fldGlobalID)除外。

字段的顺序很重要:在没有其他具有不同谓词集的查询的情况下,具有最高相对基数的字段应该排在第一位。如果不分析数据(SELECT COUNT(DISTINCT field)/COUNT(*) FROM yourtable),很难知道这是什么,但猜测顺序应该是 fldstarttime、fldemployeeno、fldprojectgroup、fldshift

如果从 fldemployeeno 对 fldshift 有依赖性(即始终是员工,或者至少超过 90% 的时间),那么在索引中包含 fldshift 只会增加它的大小,而不是提高它的效率。

你没有说你正在使用什么类型的索引 - btrees 可以处理范围,不等式的哈希。由于这里的最高基数谓词使用范围,因此 btree 索引将比基于散列的索引更有效。

于 2013-08-14T12:27:02.007 回答
1

您可以使用一个索引。这是查询,稍微重新排列:

SELECT COUNT(fldglobalid) AS PackagesDone
  FROM tblproduction
 WHERE fldemployeeno = 'APD100401'
   AND fldshift = 'B'
   AND fldprojectgroup = 'FTO'
   AND fldstarttime BETWEEN '2013-08-14 07:18:06' AND '2013-08-14 16:01:58'
   AND fldGlobalID <> 0;

(我只是将相等条件一起移到了where子句的顶部)。

查询应该使用tblproduction(fldemployeeno, fldshift, fldprojectgroup, fldstarttime). 最好也包含fldGlobalId在索引中,因此索引“覆盖”查询(查询中的所有列都在索引中)。所以,试试这个索引:

tblproduction(fldemployeeno, fldshift, fldprojectgroup, fldstarttime, fldGlobalID)
于 2013-08-14T10:46:04.100 回答