【发布时间】:2013-08-14 16:23:07
【问题描述】:
我有一个在 InnoDB 引擎上运行的名为 squares 的 MySQL 表,它大约有 2,250,000 行,表结构如下:
`squares` (
`square_id` int(7) unsigned NOT NULL,
`ref_coord_lat` double(8,6) NOT NULL,
`ref_coord_long` double(9,6) NOT NULL,
PRIMARY KEY (`square_id`),
KEY `ref_coord_lat` (`ref_coord_lat`),
KEY `ref_coord_long` (`ref_coord_long`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
第一列square_id 保存一个从0 到2.25M 的简单递增值,而ref_coord_lat 和ref_coord_long 分别保存一个点的一组十进制度的纬度和经度坐标。
这是一个只读表。不会添加额外的行,唯一需要对其运行的查询如下:
SELECT * FROM `squares` WHERE
`ref_coord_lat` BETWEEN :southLat AND :northLat AND
`ref_coord_long` BETWEEN :westLong AND :eastLong
...冒号后面的值是 PHP PDO 占位符。本质上,此查询的目标是获取表中当前位于由查询中的 4 个坐标限制的 Google 地图窗口的视口中的所有坐标点。
我已限制使用 Google Maps API 运行此查询的缩放级别,以便可以获取的最大行数为 ~5600。随着缩放级别的增加,最终的获取总数会显着降低。
直接在 PHPMyAdmin 中运行这样的示例查询需要 1.40-1.45 秒。这太长了。我已经在ref_coord_lat 和ref_coord_long 上运行标准索引,这使查询时间从约5 秒减少,但这对于最终用户期望及时响应的地图来说仍然太大了。
我的问题很简单:如何进一步优化此表/查询以提高获取结果的速度?
【问题讨论】:
-
您是否尝试过按 long 和 lat 创建索引?
-
“我已经在 ref_coord_lat 和 ref_coord_long 上运行标准索引,这将查询时间从大约 5 秒缩短”
-
我的意思是按 (long, lat) 索引 - 即两列上的索引
-
数据是否适合内存?为您的 Web 服务器购买更多 RAM 并使用 SQL 在启动时播种静态缓存。如果您需要闪电般的速度,请摆脱每个请求的 SQL 网络之旅。
-
检查 InnoDB 变量
innodb_buffer_pool的大小。如果它是 8 兆字节,这意味着您正在运行一个默认配置,这使得 MySQL 像蜗牛一样运行。增加缓冲池,你会让它运行得更快。
标签: mysql sql performance select