【问题标题】:Speed up an SQL query which uses a FullText Join加快使用全文连接的 SQL 查询
【发布时间】:2013-09-18 22:55:03
【问题描述】:

我有一种情况,我需要 JOIN 和产品数据库的内部查询,按名称对项目进行分组,然后使用名称列执行连接,因此:

SELECT p.*, p3.variants, sl.id, l.name as locationName FROM products p
LEFT JOIN (SELECT item, count(DISTINCT id) as variants FROM products GROUP BY item) p3 
ON p3.item = p.item
LEFT JOIN stockLevels sl ON sl.id=p.id 
LEFT JOIN locations l ON l.id=sl.stockLocation AND l.showStock='1' 
WHERE p.id='10459' GROUP BY p.id

弄乱了JOIN 的顺序和查询本身,我确定首先创建这个内部表并执行第一个所需的连接会影响查询的速度,但是内部连接@ 987654325@ 提供(目前)7034 行,这是不必要的,因为只需要大约 5 行。

如果我将内部连接修改为:

(SELECT item, count(DISTINCT id) as variants 
 FROM products *WHERE item LIKE '%SOME VALUE%'* GROUP BY item)

这显然减少了内连接返回的行数,而且速度大约是原来的两倍。

但是,我不能这样做,因为我没有可用于内部 where 子句的已知值。

有什么方法可以将外部表中的结果带入内部并生成引用外部的内部查询,即:

SELECT p.*, p3.variants, sl.id, l.name as locationName FROM products p
LEFT JOIN (SELECT item, count(DISTINCT id) as variants 
FROM products *WHERE item LIKE p.item * GROUP BY item) p3  << New Where Clause
ON p3.item = p.item
LEFT JOIN stockLevels sl ON sl.id=p.id 
LEFT JOIN locations l ON l.id=sl.stockLocation AND l.showStock='1' 
WHERE p.id='10459' GROUP BY p.id

我知道我上面写的内容行不通,并且理解为什么,但是有没有办法可以在这些方面取得一些成就?

以我目前数据库中的记录数量,这实际上不是问题,数据返回非常快,但我可以想象,随着时间的推移,当数据增长时,它可能会。

注意,我确实考虑过创建一个 parentId 整数列,而不是按全文分组 item 但我的应用程序中还有很多其他问题,而且它似乎并没有加快查询速度,由于与上面列出的相同原因,内部仍然必须返回所有行

还要注意,这是 MySQL

如果它有帮助,这里是 EXPLAIN 的输出

【问题讨论】:

    标签: mysql database performance join left-join


    【解决方案1】:

    您可以将相关子查询放在SELECT 子句中:

    SELECT p.*, sl.id, l.name as locationName,
           (SELECT COUNT(distinct id)
            FROM products p3
            WHERE p3.item = p.item) as variants
    FROM products p
    LEFT JOIN stockLevels sl ON sl.id=p.id 
    LEFT JOIN locations l ON l.id=sl.stockLocation AND l.showStock='1' 
    WHERE p.id='10459' GROUP BY p.id
    

    【讨论】:

      【解决方案2】:

      如果只需要 5 个,就用经典的方法:

      SELECT 
          p.*, 
          p3.variants, 
          sl.id, 
          l.name as locationName, 
          (SELECT count(DISTINCT id) 
           FROM products 
           WHERE item LIKE p.item GROUP BY item) total 
      FROM products p
      LEFT JOIN stockLevels sl 
          ON sl.id=p.id 
      LEFT JOIN locations l 
          ON l.id=sl.stockLocation AND l.showStock='1' 
      WHERE p.id='10459' GROUP BY p.id
      

      在这里您可以访问父表。

      【讨论】:

      • 为什么在您的子查询中使用LIKEGROUP BY
      • 刚刚复制了他的加入条件
      • 太好了,两种答案我都试过了,这个稍微快一点,likegroup by 减少了行数,所以我想这就是原因
      • LIKE 和 GROUP BY 绝对不可能减少行数@Jamie; LIKE 掩盖了您使用相等运算符的事实,而 GROUP BY 根本没有做任何事情,因为您没有选择要分组的列。
      • 哦,好吧,不管什么原因,它使查询更快?! :S
      猜你喜欢
      • 2016-10-07
      • 2018-02-19
      • 2013-08-28
      • 2017-08-18
      • 2012-02-07
      • 1970-01-01
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      相关资源
      最近更新 更多