【问题标题】:SQL Huge Read Only Table Performance Filter and OrderingSQL 巨大的只读表性能过滤器和排序
【发布时间】:2014-03-21 00:54:11
【问题描述】:

我有一个包含 10 亿行的表,其中包含目标设定程序的可能解决方案。 每列值的组合创建了一个成功的目标路径。我想过滤记录以显示按用户选择排序的前 10 行。有人可能想要最低的退休年龄,然后是最低的存款金额。其他人可能想要尽可能高的生存机会,然后是最高的结局平衡,...... 这是我的专栏:

age                 tinyint
retirement_age      tinyint
retirement_length   tinyint
survival            smallint  
deposit             int   
balance_start       int
balance_end         int


SLOW 10 MIN QUERY:

select top(10) age,retirement_age,retirement_length,survival,deposit,balance_start,balance_end
from TABLE
where  
age                     >= 30 
and survival            >= 8000 --OUT OF 10000
and balance_start       <= 20000
and retirement_age      >= 60
and retirement_age      <= 75
and retirement_length   >= 10 
and retirement_length   <= 25 
and deposit             >= 1000 
and deposit             <= 20000

ORDER BY  --  (COLUMN ORDER PREFERENCES UNKNOWN)
retirement_age,   
deposit, 
retirement_length desc,
balance_end desc,
age desc, 
survival desc

该查询需要 10 分钟。 所有记录都生成一次,因此不再需要对数据库进行写入/更新。我在想我应该索引每一列,但没有这样做。数据库现在是 30GB,但空间不是问题。

我已经运行了预计执行计划:

选择:0% 并行度:0% 排序:23% 表扫描:77%

【问题讨论】:

  • 我想你的意思是估计的执行计划? ;)
  • 好的,谢谢。估计的例外计划... :)

标签: sql sql-server performance tsql indexing


【解决方案1】:

您是否尝试过创建类似的索引

CREATE INDEX IX_TABLE ON [TABLE] 
(age,survival,balance_start,retirement_age,retirement_length,deposit) 
INCLUDE (balance_end)

如果不是所有字段都在WHERE clause 中使用,索引字段(age,survival,balance_start,retirement_age,retirement_length,deposit) 的顺序会有所不同,因此请确保将它们按最常用的顺序排列。

此外,包含的列的顺序没有任何区别。

由于表值不会改变,您可以创建多个这样的索引来提高其他查询的性能,它不使用WHERE clause中的所有字段

【讨论】:

  • 你为什么使用 INCLUDE(balance_start, balance_end) 而不是 INCLUDE(balance_end)? balance start 用于 WHERE 子句。我认为 INCLUDE 用于非索引列。您是说无论我的查询优先考虑哪一列,这个索引都适用于任何列优先顺序?
  • 那是正确的,所以,我错过了,那个。现在将更正。
  • 我计划总是使用尽可能多的 WHERE 子句在排序之前将数据过滤到合理的大小
  • 将所有列仅放入一个索引可将时间缩短一半。相反,我将每一列放入它自己的索引中: CREATE INDEX IX_survival ON TABLE (survival desc) CREATE INDEX IX_age ON TABLE (age asc) 等等,它的表现要好得多。
  • 当你查看执行计划时,它是否告诉你它正在使用哪个索引?
【解决方案2】:

我最终使用默认顺序在 where 和 order 子句中的每个列上创建了单独的索引:

CREATE INDEX IX_age ON TABLE (age desc)  
CREATE INDEX IX_retirement_age ON TABLE (retirement_age)  
CREATE INDEX IX_retirement_length ON TABLE (retirement_length desc)  
CREATE INDEX IX_survival ON TABLE (survival desc)   
CREATE INDEX IX_deposit ON TABLE (deposit) 
CREATE INDEX IX_balance_start ON TABLE (balance_start)     
CREATE INDEX IX_balance_end ON TABLE (balance_end desc)  

【讨论】:

    猜你喜欢
    • 2017-10-07
    • 2020-03-26
    • 2015-02-26
    • 2013-10-25
    • 2010-11-01
    • 2021-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多