mysql - 本地数据库和生产环境之间 SQL 查询运行时间的惊人差异

标签 mysql sql ruby-on-rails database

我有下一个查询:

SELECT `real_estates`.*
FROM `real_estates`
WHERE (photos_count > 0) AND
      (price > 0) AND
      (longitude is not null AND latitude is not null) AND
      `real_estates`.`rent` = 0 AND
      (estate_type = 0 or estate_type = 1) AND
      (price > 1000)
ORDER BY RAND()
LIMIT 1

数据库是MySQL。 real_estates 表中的行数在生产数据库和本地大约为 200k。但是在开发机器上运行这个查询需要 0.5 秒,而生产给我 25 秒(!)等待时间。

表引擎是 InnoDB,EXPLAIN 在两个系统上给出相同的结果。如果我删除 ORDER BY RAND(),它需要在产品上正常运行。有什么想法吗?

最佳答案

从您的查询来看,您似乎正试图从 real_estates 表中检索随机选择的行。按照你编写查询的方式,MySQL 服务器必须将所有匹配的行加载到 RAM 或硬盘驱动器数据结构中,然后对它们进行排序,取第一个,丢弃其余的。很可能您的共享生产服务器的可用 RAM 数量要少得多、磁盘驱动器速度要慢得多、其他用户很多,或者三者兼而有之。这意味着像您这样的 RAM 密集型任务可能会被迫转至磁盘。这减慢了速度。很多。你已经知道了。

您可能会考虑重构您的查询。

SELECT `real_estates`.*
FROM `real_estates`
JOIN (
        SELECT id
          FROM real_estates
         WHERE (photos_count > 0) AND
               (price > 0) AND
               (longitude is not null AND latitude is not null) AND
               `real_estates`.`rent` = 0 AND
               (estate_type = 0 or estate_type = 1) AND
               (price > 1000)
         ORDER BY RAND()
         LIMIT 1
      ) r ON real_estates.id = r.id

(我猜你的表的每一行都有一个唯一的 id 值。我也猜它被称为 id。你可能需要更改此查询以匹配您的 ID 的实际名称。)

内部查询包含您的选择逻辑。但是它不会生成一大堆数据进行排序,它只会生成 id 值。然后它随机排序它们并拿走第一个。最后,连接获取整个选定的行。

关于mysql - 本地数据库和生产环境之间 SQL 查询运行时间的惊人差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34529595/

相关文章:

android - 如何在 ListView MySql -Android 上实现搜索对话框

mysql - 查询以选择帖子并标记当前用户是否喜欢其中的一些帖子

php - 如何从sql php中的同一个表中选择多个avg

ruby-on-rails - 通过Tire gem进行Elasticsearch版本控制

php - 发布一个空变量 PHP

php - PHP 代码中的选择标签与下一个 <h2> 标签重叠

PHP - 从 MySQL DB 填充选择下拉列表,并在表单中自动填充该字段

ruby-on-rails - Rails 线程 - 多任务

ruby-on-rails - Heroku 错误 H13

php - 选择 Linux 进行开源开发