我尝试以最佳性能执行SQL查询。
首先,我想在30000个结果中随机选择一个城市,然后将结果另一个表格加入
ON `r1`.`ville_nom_reel` = `r3`.`full_name`
(基于相同的城市名称)。 对于此查询,我想添加一个过滤器以仅显示其结果
r1`.`ville_population_2012` > 10000
这是我的主要查询:大约0.010秒运行。
SELECT * FROM `inspitravel`.`villes_france_free` AS `r1`
JOIN (SELECT CEIL(RAND() * (SELECT MAX(`ville_id`) FROM `inspitravel`.`villes_france_free`)) AS `ville_id` ) AS `r2` USING (`ville_id`)
INNER JOIN `inspitravel`.`villes_booking` AS `r3`
ON `r1`.`ville_nom_reel` = `r3`.`full_name`
如何在这种情况下过滤这些结果?
`r1`.`ville_population_2012` > 10000
答案 0 :(得分:1)
我会从一个有效的查询开始:
SELECT *
FROM (SELECT vff.*
FROM inspitravel.villes_france_free vff
WHERE ville_population_2012 > 10000
ORDER BY rand()
LIMIT 1
) vff JOIN
inspitravel.villes_booking vb
ON vff.ville_nom_reel = vb.full_name;
您可以使用villes_france_free(ville_population_2012)
上的索引来提高此查询的效果。
然后,减少此查询运行时的一种安全方法是在rand()
子句中使用WHERE
。例如,您可以使用它将排序大小减少大约90%:
SELECT *
FROM (SELECT vff.*
FROM inspitravel.villes_france_free vff
WHERE ville_population_2012 > 10000 AND
rand() < 0.1
ORDER BY rand()
LIMIT 1
) vff JOIN
inspitravel.villes_booking vb
ON vff.ville_nom_reel = vb.full_name;
但是,要选择的确切值取决于匹配城镇的数量。
这样的事情通常会起作用:
SELECT *
FROM (SELECT vff.*
FROM inspitravel.villes_france_free vff CROSS JOIN
(SELECT COUNT(*) as cnt FROM inspitravel.villes_france_free vff WHERE ville_population_2012 > 10000
) x
WHERE ville_population_2012 > 10000 AND
(cnt < 100 OR rand() < 0.1 * cnt)
ORDER BY rand()
LIMIT 1
) vff JOIN
inspitravel.villes_booking vb
ON vff.ville_nom_reel = vb.full_name;