加速使用FullText Join的SQL查询

时间:2013-09-14 09:02:48

标签: mysql database performance join left-join

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

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和查询本身的顺序搞砸了,我已经确定首先创建这个内部表并执行第一个必需的连接会对查询的速度产生影响,但内部join (SELECT item, count(DISTINCT id) as variants FROM products GROUP BY item)给出(目前)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整数列,而不是通过FullText item进行分组,但我的应用程序中还有很多其他问题,而且它似乎没有加速无论如何查询,出于与上面列出的相同的原因,内部仍然必须返回所有行

另请注意,这是MySQL

如果它有帮助,那么EXPLAIN

的输出

enter image description here

2 个答案:

答案 0 :(得分:2)

您可以在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

答案 1 :(得分:0)

如果只需要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

您可以在此处访问父表。