【问题标题】:SQL query takes too longSQL 查询耗时过长
【发布时间】:2013-07-24 23:44:35
【问题描述】:

想知道是否有人可以帮助我。我有两张桌子。表 A 包含数百万行,我查找整个表,表 B 包含大约 5 万行,我再次查找整个表。我正在使用以下查询:

SELECT t1.ID as [ID], count(*) as [Total]
FROM table1 t1
RIGHT JOIN table2 t2 ON t1.data LIKE '%' + t2.field3 + '%'
AND t1.ID = t2.ID

WHERE t1.ID not LIKE ''
GROUP BY t1.ID, t1.datetime

我使用右连接的原因是,据我了解,它将获取 t2 中的所有记录(我想要的),并且仅从 t1 中获取与它们匹配的记录。另外,我在 SELECT 语句中添加了“AND t1.ID = t2.ID”,因为我认为这会加快查询速度(不查找与 t2 中的 ID 不匹配的 ID),尽管这可能会被否定正确的加入,除非我的逻辑完全错误。

另外,如果我能解释一下 JOIN 背后的逻辑 - table1 中的数据列包含很多“东西”,其中某处应该正是 t2.field3 中的内容,例如t1.data = '^ABCD^00dasdas^£ldasl32^XL0005^' 和 t2.field3 将包含 'XL0005'。

感谢任何帮助。

谢谢

【问题讨论】:

  • 你的WHERE 子句应该是WHERE t1.ID <> ''
  • 您使用哪种 DBMS? MySQL Oracle DB2..
  • 如果速度是一个问题,您的表上有哪些索引?
  • 我正在使用 SQL Server。我将尝试更改 WHERE 子句和执行计划建议。
  • 您应该使用一个或多个表将您的数据 (dbo.table1.data) 解析/提取为关系格式,然后您应该在没有此谓词 t1.data LIKE '%' + t2.field3 + '%'(即 horrible)的情况下连接所有这些表。更多,LIKE '%SomeChars%' 不是SARGable。因此,dbo.table1.data 上的索引对您没有多大帮助。

标签: sql sql-server


【解决方案1】:

如果你在子查询中移动一些逻辑会怎样

SELECT t1.ID as [ID], count(*) as [Total]
FROM (select t1.ID as [ID]
            ,t1.datetime as [DATETIME]
            ,t1.data as [DATA]
            ,t2.field3 as [FEILD3] table1 t1
             RIGHT JOIN table2 t2 ON t1.ID = t2.ID
      HAVING FIELD2 is not null AND DATA LIKE '%' + FIELD3 + '%') as t1

WHERE t1.ID not LIKE ''
GROUP BY t1.ID, t1.datetime

【讨论】:

    【解决方案2】:

    假设 ID 列已编入索引,这可能会执行得更好:

    SELECT 
      t1.ID as [ID], count(*) as [Total]
    FROM 
      table2 t2
      INNER JOIN table1 t1 ON t2.ID=t1.ID AND t1.ID <> ''
    WHERE CHARINDEX(t2.field3, t1.data) > 0
    GROUP BY t1.ID, t1.datetime
    

    还请记住,诸如 LIKE '%'+Column+'%' 或 CHARINDEX 之类的操作不会在相关列中使用任何索引。因此,如果你必须坚持特定的方法,你不应该期望有巨大的进步。

    【讨论】:

      【解决方案3】:

      问题是你在使用 Like,like 是真正的性能杀手。

      我已更改查询,请查看是否解决了目的

      SELECT ID,
             COUNT(*)
             (SELECT t.*,
                     CHARINDEX(t1.data,t2.field3) PRESENT
                FROM table1 t1
               RIGHT JOIN table2 t2 
                  ON t1.ID = t2.ID)TEMP
       WHERE ID <> '' 
         AND PRESENT > 0
       GROUP BY ID, datetime
      

      还可以尝试在 data 和 field3 列上放置索引
      试试这个。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-19
        • 1970-01-01
        • 2020-11-09
        • 1970-01-01
        • 1970-01-01
        • 2019-08-02
        相关资源
        最近更新 更多