我有一个 MySQL 查询来选择所有产品 ID,并对产品应用了特定的过滤器。这个查询 有效,但我想学习改进此查询。欢迎使用此查询的替代方案并提供解释。
SELECT kkx_products.id from kkx_products WHERE display = 'yes' AND id in (SELECT product_id FROM `kkx_filters_products` WHERE `filter_id` in (SELECT id FROM `kkx_filters` WHERE kkx_filters.urlname = "comics" OR kkx_filters.urlname = "comicsgraphicnovels") group by product_id having count(*) = 2) ORDER BY kkx_products.id desc LIMIT 0, 24
我已经包含了查询中使用的表的结构。
EXPLAINkkx_filters
;
Field Type Null Key Default Extra id int(11) unsigned NO PRI NULL auto_increment name varchar(50) NO filtergroup_id int(11) YES MUL NULL urlname varchar(50) NO MUL NULL date_modified timestamp NO CURRENT_TIMESTAMP orderid float(11,2) NO NULL
解释 kkx_filters_products
;
Field Type Null Key Default Extra filter_id int(11) NO PRI 0 product_id int(11) NO PRI 0
EXPLAIN kkx_products
;
Field Type Null Key Default Extra id int(11) NO PRI NULL auto_increment title varchar(255) NO urlname varchar(50) NO MUL description longtext NO NULL price float(11,2) NO NULL orderid float(11,2) NO NULL imageurl varchar(255) NO date_created datetime NO NULL date_modified timestamp NO CURRENT_TIMESTAMP created_by varchar(11) NO NULL modified_by varchar(11) NO NULL productnumber varchar(32) NO instock enum('yes','no') NO yes display enum('yes','no') NO yes
最佳答案
不要在条件语句中使用内联查询,而是尝试使用 EXISTS block ... http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html
您将能够看到解释计划的不同之处。在对结果集中的每条记录执行查询之前,内联 View 结果集中的每个结果都有自己的查询执行。
您会看到嵌套内联 View 如何导致成本呈指数级增长。 EXISTS 不是那样工作的。
EXISTS 的使用示例:
考虑 tbl1 有列 id 和数据。 tbl2 有列 id、parentid 和数据。
SELECT a.*
FROM tbl1 a
WHERE 1 = 1
AND EXISTS (
SELECT NULL
FROM tbl2 b
WHERE b.parentid = a.id
AND b.data = 'SOME CONDITIONAL DATA TO CONSTRAIN ON'
)
1) 我们可以假设 1 = 1 是等同于每条记录为真的条件 2) 不管我们在 EXISTS 语句中选择什么,NULL 都可以。 3)重要的是看b.parentid = a.id,这个把我们exist语句链接到结果集
关于mysql - 想学习改进慢速mysql查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5910733/