库存慢SQL查询

时间:2017-04-20 18:22:17

标签: php mysql sql

我一直在使用相同的SQL查询几个小时,它终于工作了。但是,它很慢..我一直试图优化它,但没有运气,任何帮助。这是查询(很多左连接......):

 $sql ="SELECT u.id, u.display_name, IFNULL(SUM(r.total_rating)/COUNT(r.total_rating), 0) AS avg_rating, s.title AS study FROM users u
  LEFT JOIN rating r ON u.id = r.user_id 
  LEFT JOIN usermeta m ON u.id = m.user_id
  LEFT JOIN usermeta m1 ON u.id = m1.user_id
  LEFT JOIN studies s ON m.meta_value = s.id
  WHERE m.meta_key = 'study' AND m1.meta_key = 'subjects' AND m1.meta_value REGEXP '$subjectsvalues'
  GROUP BY u.id, r.total_rating
  ORDER BY avg_rating DESC
  LIMIT 10";

用户表的表结构:

id | display_name | email
-------------------------
 1 | Khar         | ...
 2 | SantaCruz    | ...

评级表的表格结构:

id | rating_title | total_rating  | user_id
-------------------------------------------
 1 | dffd         | 5             | 1
 2 | fddfdffdd    | 4             | 1

usermeta表的表结构:

id | user_id | meta_key  | meta_value
-------------------------------------
 1 | 1       | study     | 132
 2 | 1       | subjects  | 121,231

研究表的表结构:

id | title
----------
 1 | dsdsf
 2 | sdfdf

主题值的处理如下:

$subjectsvalues = '';

$subjects = explode(",", $subjects);
foreach($subjects as $val) {
    $subjectsvalues = $subjectsvalues.",".$val.",|";
}
$subjectsvalues = $subjectsvalues."notdata";

2 个答案:

答案 0 :(得分:0)

首先,node: { __dirname: false } 是不必要的。所以试试这个:

left join

然后,我倾向于在SELECT u.id, u.display_name, AVG(r.total_rating) AS avg_rating, s.title AS study FROM users u JOIN rating r ON u.id = r.user_id JOIN usermeta m ON u.id = m.user_id JOIN usermeta m1 ON u.id = m1.user_id JOIN studies s ON m.meta_value = s.id WHERE m.meta_key = 'study' AND m1.meta_key = 'subjects' AND m1.meta_value REGEXP '$subjectsvalues' GROUP BY u.id, r.total_rating ORDER BY avg_rating DESC LIMIT 10; 上尝试索引。我假设表中的主要ID都是主键。

答案 1 :(得分:0)

我无法建议编辑Gordon Linoff的答案,所以这是一个改进的版本。除非join与自身进行比较,否则您不需要usermeta usermeta两次{/ 1}}。

SELECT u.id, u.display_name, AVG(r.total_rating) AS avg_rating, s.title AS study
FROM users u JOIN
     rating r
     ON u.id = r.user_id JOIN
     usermeta m
     ON u.id = m.user_id JOIN
     studies s
     ON m.meta_value = s.id
WHERE m.meta_key = 'study' OR (m.meta_key = 'subjects' AND m.meta_value REGEXP '$subjectsvalues')
GROUP BY u.id, r.total_rating
ORDER BY avg_rating DESC
LIMIT 10;

另外,你能解释一下你的正则表达式的效用吗?它很可能与$不匹配,表示模式的结尾位于正则表达式的开头。