[英]Optimize this SQL Query
This SQL query disgusts me. 这个SQL查询让我感到厌恶。 I didn't write it, but it's a massive cause of issues on our servers.
我没有写它,但它是我们服务器问题的一个重要原因。 I'm willing to split it up into multiple queries and do some of the processing via PHP (like, the RAND()).
我愿意将它分成多个查询并通过PHP进行一些处理(比如,RAND())。
$sql = "SELECT a.code, a.ad_id, a.position, a.type, a.image, a.url, a.height, a.width
FROM " . AD_TABLE ." a, " . USER_GROUP_TABLE . " g
WHERE (a.max_views >= a.views OR a.max_views = '0')
AND (FIND_IN_SET(" .$forum_id. ", a.show_forums) > 0 OR a.show_all_forums = '1')
AND g.user_id = " . $user->data['user_id'] . "
AND FIND_IN_SET(g.group_id, a.groups)
AND FIND_IN_SET(" . $user->data['user_rank'] . ", a.ranks)
AND a.start_time < " . time() . "
AND a.end_time > " . time() . "
AND (a.clicks <= a.max_clicks OR a.max_clicks = '0')
ORDER BY rand()";
Yeesh, I feel icky after pasting that... 是的,粘贴之后我觉得很蠢...
EDIT: Below is the results of the "EXPLAIN" on a sample query in the above format, comma delimited: 编辑:以下是以上格式的示例查询“EXPLAIN”的结果,逗号分隔:
"id","select_type","table","type","possible_keys","key","key_len","ref","rows","Extra"
1,"SIMPLE","g","ref","user_id","user_id","3","const",6,"Using temporary; Using filesort"
1,"SIMPLE","a","ALL","max_views","","","",10,"Using where"
It is 它是
You have three major issues here: 你有三个主要问题:
FIND_IN_SET
. FIND_IN_SET
。
It's not sargable, an index cannot make it faster. 这不是一件容易的事,一个索引不能让它变得更快。 Create a many-to-many relationship table (or tables).
创建多对多关系表(或多个表)。
a.start_time < GETDATE() AND a.end_time > GETDATE()
MySQL
is not good in optimizing that. MySQL
不善于优化。 You can keep you timespans as geometry boxes and create a SPATIAL INDEX
over them, this will be much faster (though less readable) 您可以将时间跨度作为几何框保留,并为它们创建一个
SPATIAL INDEX
,这将更快(尽管可读性较差)
ORDER BY RAND()
If you are using this to sample data (ie you don't need all rows but rather a small random subset), there is a more efficient way to do this, described in this article in my blog: 如果您使用它来对数据进行采样(即您不需要所有行而是需要一个小的随机子集),那么有一种更有效的方法可以执行此操作,如本文在我的博客中所述:
This will add some more code in your php class/function. 这将在你的php类/函数中添加更多代码。
I am guessing your problem lies with the dates. 我猜你的问题在于日期。
AND a.start_time < " . time() . "
AND a.end_time > " . time() . "
I would try putting indexes on these fields and see if that helps. 我会尝试在这些字段上放置索引,看看是否有帮助。 Comparing dates causes the database to compare to each row in the table.
比较日期会导致数据库与表中的每一行进行比较。
If you execute this a lot.. try and use bind variables (instead of string concatenation) .. so the query does not have to be parsed every single time.. 如果你执行这么多..尝试并使用绑定变量(而不是字符串连接)..所以查询不必每次都被解析..
edit: Sorry..didn't see the MYSQL tag. 编辑:抱歉..没有看到MYSQL标签。 Unless it's changed recently I don't think MySQL likes prepared statements.
除非最近改变,否则我认为MySQL不喜欢预备语句。 ORACLE on the other hand LOVES them.
另一方面,ORACLE喜欢它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.