1

我有一个 MySQL 查询来选择所有产品 ID,并将某些过滤器应用于产品。此查询有效,但我想学习改进此查询。欢迎使用此查询的替代方案并提供解释。

选择 kkx_products.id 从 kkx_products WHERE display = 'yes' AND id in
    (从`kkx_filters_products`中选择product_id,其中`filter_id`在
       (从 `kkx_filters` 中选择 id,其中 kkx_filters.urlname = "comics" 或 kkx_filters.urlname = "comicsgraphicnovels")
    按具有 count(*) = 2) 的 product_id 分组
    ORDER BY kkx_products.id desc LIMIT 0, 24

我已经包含了查询中使用的表的结构。

解释kkx_filters

字段类型 Null Key 默认 Extra
id int(11) 无符号 NO PRI NULL auto_increment
名称 varchar(50) 否             
filtergroup_id int(11) 是 MUL NULL     
urlname varchar(50) NO MUL NULL     
date_modified 时间戳 NO CURRENT_TIMESTAMP    
orderid float(11,2) 无 NULL    

解释kkx_filters_products

字段类型 Null Key 默认 Extra
filter_id int(11) 无优先级 0    
product_id int(11) 无优先级 0   

解释kkx_products

字段类型 Null Key 默认 Extra
id int(11) NO PRI NULL auto_increment
标题 varchar(255) 否           
urlname varchar(50) NO MUL        
描述长文本 NO NULL   
价格浮动(11,2)NO NULL   
orderid float(11,2) 无 NULL   
imageurl varchar(255) 否            
date_created 日期时间 NO NULL    
date_modified 时间戳 NO CURRENT_TIMESTAMP    
created_by varchar(11) NO NULL    
modified_by varchar(11) NO NULL   
产品编号 varchar(32) 否           
库存枚举('是','否')否是    
显示枚举('yes','no') 否 是    
4

1 回答 1

3

不要在条件语句中使用内联查询,而是尝试使用 EXISTS 块... http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html

您将能够看到您的解释计划中的差异。在您为结果集中的每条记录执行查询之前,并且该内联视图结果集中的每个结果都有自己的查询执行。

您会看到嵌套的内联视图如何导致成本呈指数级增长。EXISTS 不是那样工作的。

EXISTS 的使用示例:

考虑 tbl1 有列 id 和 data。tbl2 具有列 id、parentid 和 data。

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 是某个条件,对于每条记录都等于 true 2)无论我们在 EXISTS 语句中选择什么,NULL 都可以。3)看b.parentid = a.id很重要,这将我们的exist语句链接到结果集

于 2011-05-06T11:35:02.853 回答