大表中的慢SQL,按时间戳过滤(int12)

时间:2011-08-22 17:45:39

标签: mysql sql

我有一个慢查询的问题,做一个“简单”选择..我不明白是什么问题...这是一个大表...但它是一个简单的查询...

表格:

business: (1.000.000 reg)
id (INDEX PRIMARY INT(11) UNSIGNED)
active (INDEX TINYINT(1))

products: (32.000.000 reg)
id (INDEX PRIMARY INT(11) UNSIGNED)
business_id (INDEX INT(11) UNSIGNED)
offer_start (INDEX INT(12) UNSIGNED) (timestam unix)
offer_end (INDEX INT(12) UNSIGNED) (timestamp unix)
price_offer (VARCHAR(10)) (price with decimals)
active (INDEX TINYINT(1))

business.id,products.id,products.offer_start和products.offer_end是INDEX(分离)

当我这样做时:

SELECT SQL_NO_CACHE * FROM products 
LEFT JOIN business ON business.id = products.business_id 
WHERE
 (business.active = '1' AND business.paylimit > 1314029906) 
AND 
 (products.active = '1' AND products.offer_start < 1314029906 AND products.offer_end > 1314029906 AND products.price_offer > 0) 
LIMIT 0,10

需要21秒。 问题是:products.offer_start < 1314029906 AND products.offer_end > 1314029906需要大约20秒才能给我结果

是否可以进行此查询,过滤其他表单以加快速度?

2 个答案:

答案 0 :(得分:2)

有关您的表架构的一些注意事项:

  1. offer_start(INDEX INT(12)UNSIGNED) - 12没有意义,因为INT中的最大符号是11. offer_end
  2. 相同
  3. active(INDEX TINYINT(1)) - 索引没用,因为1000000上的基数将是2 - 1或0
  4. price_offer(VARCHAR(10)) - 您可以使用浮点数或小数。 products.price_offer&gt; 0会更快。

答案 1 :(得分:0)

尝试

SELECT SQL_NO_CACHE * FROM products 
    LEFT JOIN business ON business.id = products.business_id 
WHERE business.paylimit > 1314029906
    AND products.offer_start < 1314029906
    AND products.offer_end > 1314029906
    AND products.price_offer > 0
    AND business.active = '1'
LIMIT 0,10

MySQL从左到右处理过滤器,因此请确保选择性最强的条件(返回最少的行)位于左侧。在条件的最左侧business.active = '1'可能使用索引,但如果它的选择性为50%,那么其余条件不使用索引。

您可能需要阅读手册中的How MySQL Uses Indexes

编辑: 关于MySQL如何使用索引的简短说明:3 ways MySQL uses indexes