简体   繁体   English

PHP:如何在单个查询中优化这些MySQL查询?

[英]PHP: How can I optimize these MySQL queries in a single query?

Is it possible to optimize the following into a single query? 是否可以将以下内容优化为一个查询?

I am assuming here that a single query would be more efficient that multiple queries using a temporary table, so please let me know if my assumption is incorrect. 我在这里假设单个查询比使用临时表的多个查询更有效,所以请让我知道我的假设是否正确。

$id is the current memberid. $id是当前的成员ID。 $list is a list of itemids to be removed from the final results (eg items already downloaded). $list是要从最终结果中删除的itemid的列表(例如,已下载的项目)。

What this query is supposed to do it find the top 500 members who have downloaded similar items to the $id member. 该查询应该执行的操作是找到将类似项目下载到$id成员的前500名成员。 Then find all the items that these members have downloaded, ranked by a score based on the number of similar downloads from each member and the total number of downloads of each item. 然后找到这些成员已下载的所有项目,并根据每个成员的相似下载次数和每个项目的下载总数,按得分进行排名。 The final result is therefore a list of recommendations for the $id member. 因此,最终结果是$id成员的建议列表。

The queries are: 查询是:

mysql_query('CREATE TEMPORARY TABLE temp1 ENGINE=MEMORY AS
(SELECT a.memberid, COUNT(*) `score` FROM table_downloads a INNER JOIN
(SELECT itemid FROM table_downloads WHERE memberid='.$id.') b ON a.itemid = b.itemid
WHERE a.memberid!='.$id.' GROUP BY a.memberid HAVING score>0 ORDER BY score DESC LIMIT 500)');

$res=mysql_query('SELECT table_downloads.itemid,COUNT(table_downloads.itemid*temp1.score) AS score2
FROM table_downloads,temp1
WHERE table_downloads.memberid=temp1.memberid AND table_downloads.itemid NOT IN ('.$list.') 
GROUP BY table_downloads.itemid
ORDER BY score2 DESC LIMIT 30');

mysql_query('DROP TABLE temp1');

It's possible that this query might take too long as to be unusable if there were several million rows. 如果有几百万行,此查询可能会花费太长时间以致无法使用。 Any advice on ensuring it is executes quickly would also be greatly appreciated. 任何有关确保其快速执行的建议也将不胜感激。

* I am using mysql_query deliberately. * 我故意使用mysql_query。 Please do not tell me to use mysqli.* 请不要告诉我使用mysqli。*

  1. It's not possible to do with mysql_query() 不可能与mysql_query()
  2. It's a mistake to think that joining 3 calls into one would save something noticeable in this case 认为将3个电话加入一个电话可以节省一些明显的情况是错误的

And to be clear it's a very common delusion - to think that a single messy query would run faster than multiple. 明确地说,这是一个非常普遍的错觉-认为单个凌乱的查询的运行速度比多重查询快。 It wouldn't. 不会的。

Out of interest I had a play. 出于兴趣我玩了。

I think it is possible, although not pretty and I suspect slower than your current script. 我认为这是可能的,尽管它并不漂亮,而且我怀疑它比您当前的脚本慢。

SELECT table_downloads.itemid, COUNT(table_downloads.itemid * temp1.score) AS score2
FROM table_downloads
INNER JOIN (SELECT a.memberid, COUNT(*) `score` 
            FROM table_downloads a 
            INNER JOIN table_downloads b
            ON  a.itemid = b.itemid AND b.memberid='.$id.' AND a.memberid=b.memberid
            GROUP BY a.memberid 
            ORDER BY score DESC
            LIMIT 500) temp1
ON table_downloads.memberid = temp1.memberid 
WHERE table_downloads.itemid NOT IN ('.$list.') 
GROUP BY table_downloads.itemid
ORDER BY score2 DESC 
LIMIT 30

Not really tested though (don't know your table layouts) 尚未经过实际测试(不知道您的表布局)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM