MySQL查询优化 - 随机记录

时间:2012-03-13 04:43:23

标签: php mysql

我的MySQL查询时间很糟糕。我已经度过了周末的大部分时间,今天的大部分时间都在尝试使这个查询运行得更快一些。我的速度要快得多,但我知道我可以做得更好。

SELECT m.id,other_fields,C.contacts_count FROM marketingDatabase AS m 
LEFT OUTER JOIN 
 (SELECT COUNT(*) as contacts_count, rid 
  FROM contacts 
  WHERE status = 'Active' AND install_id = 'XXXX' GROUP BY rid) as C
 ON C.rid = m.id 
WHERE (RAND()*2612<50) 
  AND do_not_call != 'true' 
  AND `ACTUAL SALES VOLUME` >= '800000'  
  AND `ACTUAL SALES VOLUME` <= '1200000' 
  AND status = 'Pending'
  AND install_id = 'XXXXX' 
ORDER BY RAND()

我有'install_id','category'和'status'的索引,但EXPLAIN显示它是基于9100行进行排序。

我的解释在这里: https://s3.amazonaws.com/jas-so-question/Screen+Shot+2012-03-13+at+12.34.04+AM.png

有人建议我能做些什么来加快速度吗?查询的整个要点是从帐户的记录(install_id)中选择一个随机记录,该记录与销售量,状态和do_not_call等特定条件相匹配。我目前正在收集25条记录并对其进行缓存(使用PHP),因此我每25次请求只需运行一次此查询,但我已经处理了每天数千条请求。它目前需要0.2秒才能运行。我意识到通过使用ORDER BY RAND()我已经取得了重大的性能提升,但它只是排序了25行。

提前感谢您的帮助。

**编辑:我忘了提及'contact_sort'索引在'contacts'表上,并索引install_id,status和rid。 (在marketingDatabase中删除引用记录ID,以便它知道联系人所属的记录。

**编辑2:查询中的2612数字表示marketingDatabase中符合条件(install_id,status,实际销售量等)的行数。

2 个答案:

答案 0 :(得分:1)

由于我没有看到您的索引定义,我不确定它们是否正确。该查询将受益于以下索引:

  1. contacts上的复合索引(install_id,status,rid)

  2. marketingDatabase上的综合索引(install_id,status,`ACTUAL SALES VOLUME`)

答案 1 :(得分:0)

我玩了几个查询,我认为你永远不会得到索引查询来使用RAND(),特别是当你在WHERE子句和ORDER中使用它时BY子句。如果可能的话,我会在PHP逻辑中引入随机元素,并且可能会看两个简单的查询是否比一个相当复杂的查询更有意义。除此之外,您在随机结果集上有LEFT OUTER JOIN,这也可能会增加必须完成的工作量。

总之,我的猜测是 - 重写以排除RAND,看看你是否可以摆脱LEFT OUTER JOIN。两个简单的索引查询,中间有一点PHP可能会好很多。