按虚拟键排序在mysql中需要很长时间

时间:2014-01-01 18:45:54

标签: mysql

SELECT p . * , (
  SELECT (
    SELECT COUNT( * ) 
    FROM sales s
    WHERE s.affiliate !=  ''
      AND s.pid = p.pid
      AND s.saletype =  'sale' )
  ) AS popular
FROM products p
INNER JOIN members m ON m.uname = p.vendor
WHERE (m.mpid = p.pid OR p.marketavail =  'yes')
  AND p.showinmarket =  'yes'
  AND p.pname !=  ''
  AND p.pdesc !=  ''
  AND p.active =  'yes'
ORDER BY popular DESC

在这里,如果我使用ORDER BY流行,则需要17秒才能加载。没有这种排序,查询将在4秒内执行。 请告诉我为什么在按虚拟列排序时需要花费太多时间?

所有表都有必需列的索引,因此索引不是我猜的问题。如果我为单个产品运行select count(*),它将以毫秒为单位执行。 还有一个错误,我看到,如果我删除SELECT字(我的SQL中的第二个选择单词),执行需要105秒。

请告诉我是否需要提供更多信息。

由于排序的这种延迟,我使用php而不是mysql进行排序。请帮助我做得更好。

提前谢谢。

1 个答案:

答案 0 :(得分:1)

请尝试此查询

SELECT p.column1,
       p.column2,
       p.column3,
       COUNT(s.pid) as popular
FROM products p
INNER JOIN members m ON m.uname = p.vendor
LEFT JOIN sales s ON s.pid = p.pid AND s.affiliate != '' AND s.saletype = 'sale'
WHERE (m.mpid = p.pid OR p.marketavail =  'yes')
  AND p.showinmarket =  'yes'
  AND p.pname !=  ''
  AND p.pdesc !=  ''
  AND p.active =  'yes'
  GROUP BY p.column1,p.column2,p.column3
ORDER BY popular DESC

column1,column2,column3只是您想要的列的示例,因为您选择*我不知道产品中的列名是什么。所以将它们更改为您的实际列名。

编辑:尝试此查询,看看它是否更快

SELECT p.pname, p.vendor, p.pid, 
   COUNT( s.pid ) AS popular 
   FROM products p INNER JOIN members m ON m.uname = p.vendor 
   LEFT JOIN 
       (SELECT pid FROM sales
        WHERE affiliate != ''
          AND saletype = 'sale'
        )s
    ON (s.pid = p.pid) 
   WHERE ( m.mpid = p.pid OR p.marketavail = 'yes' ) 
       AND p.showinmarket = 'yes' AND p.pname != '' 
       AND p.pdesc != '' 
       AND p.active = 'yes' 
   GROUP BY p.pid, p.pname 
   ORDER BY popular DESC

如果运行速度更快,您可以像对此查询一样预过滤产品,看看它是否运行得更快

SELECT p.pname, p.vendor, p.pid, 
   COUNT( s.pid ) AS popular 
   FROM (SELECT pname,vendor,pid,marketavail
         FROM products
         WHERE showinmarket = 'yes' 
           AND pname != ''  
           AND pdesc != ''
           AND active = "yes"
        )p 
   INNER JOIN members m ON m.uname = p.vendor 
   LEFT JOIN 
       (SELECT pid FROM sales
        WHERE affiliate != ''
          AND saletype = 'sale'
        )s
    ON (s.pid = p.pid) 
   WHERE ( m.mpid = p.pid OR p.marketavail = 'yes' )
   GROUP BY p.pid, p.pname 
   ORDER BY popular DESC