fab*_*rik 88 mysql random performance
我想优化我的查询,所以我调查一下mysql-slow.log.
我的大多数慢查询包含ORDER BY RAND().我无法找到解决此问题的真正解决方案.Theres是MySQLPerformanceBlog的可能解决方案,但我认为这还不够.在未经优化(或经常更新,用户管理)的表上,它不起作用,或者我需要运行两个或更多查询才能选择我PHP生成的随机行.
这个问题有什么解决方案吗?
一个虚拟的例子:
SELECT accomodation.ac_id,
accomodation.ac_status,
accomodation.ac_name,
accomodation.ac_status,
accomodation.ac_images
FROM accomodation, accomodation_category
WHERE accomodation.ac_status != 'draft'
AND accomodation.ac_category = accomodation_category.acat_id
AND accomodation_category.acat_slug != 'vendeglatohely'
AND ac_images != 'b:0;'
ORDER BY
RAND()
LIMIT 1
Run Code Online (Sandbox Code Playgroud)
Qua*_*noi 67
试试这个:
SELECT *
FROM (
SELECT @cnt := COUNT(*) + 1,
@lim := 10
FROM t_random
) vars
STRAIGHT_JOIN
(
SELECT r.*,
@lim := @lim - 1
FROM t_random r
WHERE (@cnt := @cnt - 1)
AND RAND(20090301) < @lim / @cnt
) i
Run Code Online (Sandbox Code Playgroud)
这是特别有效的MyISAM(因为它COUNT(*)是即时的),但即使InnoDB它的10效率也高于ORDER BY RAND().
这里的主要思想是我们不进行排序,而是保留两个变量并计算running probability当前步骤中要选择的行.
有关详细信息,请参阅我的博客中的这篇文章
更新:
如果您需要选择一个随机记录,请尝试以下方法:
SELECT aco.*
FROM (
SELECT minid + FLOOR((maxid - minid) * RAND()) AS randid
FROM (
SELECT MAX(ac_id) AS maxid, MIN(ac_id) AS minid
FROM accomodation
) q
) q2
JOIN accomodation aco
ON aco.ac_id =
COALESCE
(
(
SELECT accomodation.ac_id
FROM accomodation
WHERE ac_id > randid
AND ac_status != 'draft'
AND ac_images != 'b:0;'
AND NOT EXISTS
(
SELECT NULL
FROM accomodation_category
WHERE acat_id = ac_category
AND acat_slug = 'vendeglatohely'
)
ORDER BY
ac_id
LIMIT 1
),
(
SELECT accomodation.ac_id
FROM accomodation
WHERE ac_status != 'draft'
AND ac_images != 'b:0;'
AND NOT EXISTS
(
SELECT NULL
FROM accomodation_category
WHERE acat_id = ac_category
AND acat_slug = 'vendeglatohely'
)
ORDER BY
ac_id
LIMIT 1
)
)
Run Code Online (Sandbox Code Playgroud)
这假设您ac_id的分布或多或少均匀分布.
Dis*_*oat 13
这取决于你需要的随机性.您链接的解决方案非常适合IMO.除非你在ID字段中有很大的空白,否则它仍然是随机的.
但是,您应该能够在一个查询中使用它(用于选择单个值):
SELECT [fields] FROM [table] WHERE id >= FLOOR(RAND()*MAX(id)) LIMIT 1
Run Code Online (Sandbox Code Playgroud)
其他方案:
random表的永久浮点字段,并用随机数填充它.然后,您可以在PHP中生成一个随机数"SELECT ... WHERE rnd > $random"| 归档时间: |
|
| 查看次数: |
64338 次 |
| 最近记录: |