多个Join / Inner Join SQL的过滤条件

时间:2017-02-26 14:11:42

标签: mysql sql

我尝试以最佳性能执行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

1 个答案:

答案 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;