【问题标题】:Slow running SQL query on a large table在大表上运行缓慢的 SQL 查询
【发布时间】:2018-10-10 16:09:37
【问题描述】:

我在 sql server 上运行以下查询。

select * from table1 where added_on in ('2018-09-26','2018-10-02') and uid=309

我的表包含超过 3000 万条记录。但是上面的查询将导致少于 200 条记录,因为它需要 30-40 秒。

我的表上有聚集索引和非聚集索引。

主键的聚集索引和added_on(日期字段)的非聚集索引

还有什么我可以用来放在桌子上以加快结果时间

【问题讨论】:

  • 如果英语有 crore 的定义,好的。如果没有 - 是的。请用英语。请添加查询计划。此外,如果您删除并使用 2 个正常条件,行为会改变吗? WITH 查询计划。还有什么硬件?
  • 3 千万 == 30,000,000 行?无论如何,在 [uid] 和 [add_on] 上创建一个索引:CREATE INDEX IX_Composite ON [table1] ([uid], [add_on]);
  • 尝试改变where子句的顺序,去掉*并在uid,added_on上创建索引。
  • @TomTom 根据谷歌,Crore is a unit in Indian numerical system which is equivalent to 10 million(感谢 OP,我今天学到了一个新词)。
  • 根据网站规则,这里是英文而不是印度。

标签: sql sql-server optimization


【解决方案1】:

您需要一个涵盖您正在搜索的两个字段的索引。试试这个:

CREATE INDEX IX_Composite ON [table1] ([uid], [added_on]);

【讨论】:

  • @MitchWheat 还有,它可能使用扫描索引而不是搜索。
  • 如果不使用索引,您的评论有些多余! :)
  • 实际上,如果 uid 具有足够的选择性 - 或者日期是 - 索引的其他部分大多是无关紧要的。是的,您可以将所有可能的索引都扔给它——这并不是一个明智的决定。这就是为什么查询计划好的原因 - 提供选择性和决策理由的概念,而不是盲目添加索引。
  • 所有真正的 cmets。我可能应该避免发布 spitball 答案。
  • 选择 * 仍然可以使用该索引进行查找。
【解决方案2】:

我不确定,但试试这个:

  1. 创建索引

    CREATE INDEX index_name ON table1 (added_on, uid);
    
  2. 这部分代码

    where added_on in ('2018-09-26','2018-10-02')
    

    你把日期写在''中,比如字符串类型,也许数据库试图将它转换为浪费时间的日期类型。 试试这个:

    where added_on in (to_date('2018-09-26','yyyy-mm-dd'),to_date('2018-10-02','yyyy-mm-dd'))
    

【讨论】:

    【解决方案3】:

    首先尽量不要使用select *,从这个查询中指定你需要的列

    你可以创建和索引

        CREATE INDEX index_name ON table1 (added_on, uid) include (...what you select...);
    

    这样你就可以进行索引搜索了。

    也可以尝试重建主键并更新统计信息。如果表索引上有很多插入/更新操作,我就已经过时了。

    除了可以对表进行分区之外,它还可以显着提高性能。根据您拥有的数据量,您可以例如。按日期分区,我认为这可能会真正提高性能。

    最后,检查一下当时db上是否没有其他繁重的工作

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多