【发布时间】:2011-11-26 16:45:01
【问题描述】:
我正在使用 MySQL 5.5.14 版从 500 万行的表中运行以下查询 QUERY 1:
SELECT P.ID, P.Type, P.Name, P.cty
, X(P.latlng) as 'lat', Y(P.latlng) as 'lng'
, P.cur, P.ak, P.tn, P.St, P.Tm, P.flA, P.ldA, P.flN
, P.lv, P.bd, P.bt, P.nb
, P.ak * E.usD as 'usP'
FROM PIG P
INNER JOIN EEL E
ON E.cur = P.cur
WHERE act='1'
AND flA >= '1615'
AND ldA >= '0'
AND yr >= (YEAR(NOW()) - 100)
AND lv >= '0'
AND bd >= '3'
AND bt >= '2'
AND nb <= '5'
AND cDate >= NOW()
AND MBRContains(LineString( Point(39.9097, -2.1973)
, Point(65.5130, 41.7480)
), latlng)
AND Type = 'g'
AND tn = 'l'
AND St + Tm - YEAR(NOW()) >= '30'
HAVING usP BETWEEN 300/2 AND 300
ORDER BY ak
LIMIT 100;
使用 Index (Type, tn, act, flA),我能够在 800ms 内获得结果。在QUERY 2中,我将ORDER BY 子句更改为lv,我也能够在类似的时间内获得结果。在 QUERY 3 中,我将 ORDER BY 子句更改为 ID,平均 10 次试验,查询时间显着减慢到整整 20 秒。
运行EXPLAIN SELECT 语句会产生完全相同的查询执行计划:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: P
type: range
possible_keys: Index
key: Index
key_len: 6
ref: NULL
rows: 132478
Extra: Using where; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: E
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 3
ref: BS.P.cur
rows: 1
Extra:
我的问题是:为什么在 QUERY 3 中按 ID 排序的速度比其他的慢?
部分表定义如下:
CREATE TABLE `PIG` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`lv` smallint(3) unsigned NOT NULL DEFAULT '0',
`ak` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `id_ca` (`cty`,`ak`),
KEY `Index` (`Type`, `tn`, `act`, `flA`),
) ENGINE=MyISAM AUTO_INCREMENT=5000001 DEFAULT CHARSET=latin1
CREATE TABLE `EEL` (
`cur` char(3) NOT NULL,
`usD` decimal(11,10) NOT NULL,
PRIMARY KEY (`cur`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
更新:在对各种ORDER BYs 选项进行广泛测试后,我确认恰好是主键的 ID 列是唯一导致查询时间缓慢的列。
【问题讨论】:
-
不是答案,而是对您的查询/数据库的评论。为了您和他人,请使用相关名称。如果你离开这个应用程序一个月左右,然后回来。您将必须弄清楚每列包含什么。对于这样的论坛上的问题,它没有多大意义。这将需要一些额外的输入,但这不应该有任何问题。
-
@Topener:很抱歉,如果在列名上使用短格式会让您更难理解我的问题。我担心透露申请。希望你能理解;p
-
在没有
ORDER BY而使用LIMIT 100的情况下,查询需要运行多长时间? -
你能描述一下
EEL吗? -
@radiospiel,是的,
HAVING可以在没有GROUP BY的情况下使用。您可以在 Stackoverflow 上创建一个单独的问题,而不是在此处发布。
标签: mysql performance query-optimization