优化简单的 mysql 查询,对两列进行排序
optimise simple mysql query with order by on two columns
我才刚刚开始 运行 解释我的查询,发现类型是 All 并且我正在使用文件排序。
即使是最简单的查询,我也不确定如何优化,如果有人可以就以下查询提供指导,该查询主要按名字检索用户和订单,其次按姓氏检索用户和订单:
SELECT UserID, TRIM(FName) AS FName, TRIM(SName) as SName, pic
FROM users WHERE Blocked <> 1
ORDER BY FName, SName
LIMIT ?, 10
Table创建如下:
CREATE TABLE IF NOT EXISTS `users` (
`UserID` int(11) NOT NULL,
`FName` varchar(25) NOT NULL,
`SName` varchar(25) NOT NULL,
`Pword` varchar(50) NOT NULL,
`Longitude` double NOT NULL,
`Latitude` double NOT NULL,
`DateJoined` bigint(20) NOT NULL,
`Email` varchar(254) NOT NULL,
`NotificationID` varchar(256) NOT NULL,
`Pic` varchar(500) DEFAULT NULL,
`Radius` int(11) NOT NULL,
`ads` tinyint(1) NOT NULL,
`Type` varchar(5) NOT NULL,
`Blocked` tinyint(4) NOT NULL
) ENGINE=MyISAM AUTO_INCREMENT=1469 DEFAULT CHARSET=latin1;
解释如下:
id : 1
select_type : SIMPLE
table : users
type : ALL
possible_keys : NULL
key : NULL
key_len : NULL
ref : NULL
rows : 1141
Extra : Using where; Using filesort
如果你想优化这个查询,你可以在 where 条件下的字段上创建一个索引
CREATE INDEX id_users_blocked ON users (Blocked) ;
优化取决于被阻止 <> 1 的用户数量
如果这些很少,则不会在特定方面有所改善..但在解释中你不应该看到全部。
您还可以在索引字段中添加 fname、sname,但是使用 trim 作为一种方式和字段 pic 的需要不能使该索引具有性能.. 因为如果 firsta case 字段通常像 trim 这样的函数不是从索引中获取的,第二个不是带有像 pic 这样的字段的索引。所以在 table 行的访问是强制性的。
添加索引(已阻止,FName,SName)
如果可能的话,将 where 更改为 Blocked = 0
SELECT UserID, TRIM(FName) AS FName, TRIM(SName) as SName, pic
FROM users WHERE Blocked <> 1
ORDER BY FName, SName
LIMIT ?, 10
让我们分析一下您的查询。您已使用子句 WHERE
提取列 Blocked
和 value <> 1
的值。改进此子句取决于列 Blocked
中值的数据分布。如果只有一小部分数据包含值
blocked <> 1
在 blocked
列上使用 INDEX
会提高性能。在另一种情况下 INDEX
对你没有帮助。
您还为 table 的每条记录使用了 TRIM
函数。如果删除它,您将提高性能。
当然,排序也会影响查询性能。
我才刚刚开始 运行 解释我的查询,发现类型是 All 并且我正在使用文件排序。
即使是最简单的查询,我也不确定如何优化,如果有人可以就以下查询提供指导,该查询主要按名字检索用户和订单,其次按姓氏检索用户和订单:
SELECT UserID, TRIM(FName) AS FName, TRIM(SName) as SName, pic
FROM users WHERE Blocked <> 1
ORDER BY FName, SName
LIMIT ?, 10
Table创建如下:
CREATE TABLE IF NOT EXISTS `users` (
`UserID` int(11) NOT NULL,
`FName` varchar(25) NOT NULL,
`SName` varchar(25) NOT NULL,
`Pword` varchar(50) NOT NULL,
`Longitude` double NOT NULL,
`Latitude` double NOT NULL,
`DateJoined` bigint(20) NOT NULL,
`Email` varchar(254) NOT NULL,
`NotificationID` varchar(256) NOT NULL,
`Pic` varchar(500) DEFAULT NULL,
`Radius` int(11) NOT NULL,
`ads` tinyint(1) NOT NULL,
`Type` varchar(5) NOT NULL,
`Blocked` tinyint(4) NOT NULL
) ENGINE=MyISAM AUTO_INCREMENT=1469 DEFAULT CHARSET=latin1;
解释如下:
id : 1
select_type : SIMPLE
table : users
type : ALL
possible_keys : NULL
key : NULL
key_len : NULL
ref : NULL
rows : 1141
Extra : Using where; Using filesort
如果你想优化这个查询,你可以在 where 条件下的字段上创建一个索引
CREATE INDEX id_users_blocked ON users (Blocked) ;
优化取决于被阻止 <> 1 的用户数量
如果这些很少,则不会在特定方面有所改善..但在解释中你不应该看到全部。
您还可以在索引字段中添加 fname、sname,但是使用 trim 作为一种方式和字段 pic 的需要不能使该索引具有性能.. 因为如果 firsta case 字段通常像 trim 这样的函数不是从索引中获取的,第二个不是带有像 pic 这样的字段的索引。所以在 table 行的访问是强制性的。
添加索引(已阻止,FName,SName)
如果可能的话,将 where 更改为 Blocked = 0
SELECT UserID, TRIM(FName) AS FName, TRIM(SName) as SName, pic
FROM users WHERE Blocked <> 1
ORDER BY FName, SName
LIMIT ?, 10
让我们分析一下您的查询。您已使用子句 WHERE
提取列 Blocked
和 value <> 1
的值。改进此子句取决于列 Blocked
中值的数据分布。如果只有一小部分数据包含值
blocked <> 1
在 blocked
列上使用 INDEX
会提高性能。在另一种情况下 INDEX
对你没有帮助。
您还为 table 的每条记录使用了 TRIM
函数。如果删除它,您将提高性能。
当然,排序也会影响查询性能。