3

item我在包含 400k 记录的 InnoDb 表中有一个查询(仅...)。我需要对表示层的结果进行分页(每页 60 个),因此我使用LIMIT取决于要显示的页面的值。

查询是(110000偏移量只是一个例子):

SELECT i.id, sale_type, property_type, title, property_name, latitude,
       longitude,street_number, street_name, post_code,picture, url,
       score, dw_id, post_date
FROM item i WHERE picture IS NOT NULL AND picture != ''
AND sale_type = 0
ORDER BY score DESC  LIMIT 110000, 60;

在我的机器上运行这个查询大约需要 1 秒。在我们的测试服务器上运行这个查询需要 45-50 秒。

EXPLAIN 都是一样的:

+----+-------------+-------+-------+---------------+-----------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys | key       | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+---------------+-----------+---------+------+--------+-------------+
|  1 | SIMPLE      | i     | index | NULL          | IDX_SCORE | 5       | NULL | 110060 | Using where |
+----+-------------+-------+-------+---------------+-----------+---------+------+--------+-------------+

查询时唯一的配置差异show variables是:

  • innodb_use_native_aio. 它在测试服务器上启用,而不是在我的机器上。我尝试禁用它,但没有看到任何重大变化
  • innodb_buffer_pool_size测试服务器1G,我的机器2G

测试服务器有 2Gb 的内存,2 核 CPU:

  • mysqld 始终使用 > 65% 的 RAM,但仅增加 1-2% 运行以上查询
  • mysqld 在运行上述查询时使用 14% 的 CPU,空闲时不使用

我的本地机器有 8Gb,8 核 CPU:

  • mysqld 一直使用 28% 的 RAM,并且在运行上述查询时并没有真正增加(或者在很短的时间内我可以看到它)
  • mysqld 在运行上述查询时使用 48% 的 CPU,空闲时不使用

我可以在哪里以及如何做才能在测试服务器上获得相同的性能?RAM 和/或 CPU 是否太低?

更新

我已经设置了一个具有相同规格但 8G 内存和 4 核 CPU 的新测试服务器,性能刚刚跃升至与我的机器相似的值。原来的服务器似乎没有使用所有的 RAM/CPU,为什么性能这么差?

4

1 回答 1

2

杀死性能的最可靠方法之一是让 MySQL 扫描不适合内存的索引。因此,在查询期间,它必须将部分索引加载到缓冲池中,然后逐出该部分并加载索引的另一部分。在查询期间像这样在缓冲池中造成流失会导致大量 I/O 负载,这会使其非常慢。磁盘 I/O 比 RAM 慢大约 100,000 倍。

因此,如果您的索引是 1.5GB,那么 1GB 缓冲池和 2GB 缓冲池之间存在很大差异。

另一个提示:你真的不想使用LIMIT 110000, 60. 这导致 MySQL 从缓冲池中读取 110000 行(如果需要,可能从磁盘加载它们)只是为了丢弃它们。还有其他方法可以更有效地对结果集进行分页。

请参阅使用 MySQL 优化分页等文章。

于 2013-05-01T05:02:40.153 回答