简体   繁体   中英

optimise simple mysql query with order by on two columns

I've only just began to run explain on my queries and see that the type is All and I'm using filesort.

I'm not sure how to optimise even the simplest of queries, if anyone could provide guidance on the following query which just retrieves users and orders by their first name primarily and second name secondarily:

SELECT UserID, TRIM(FName) AS FName, TRIM(SName) as SName, pic
FROM users WHERE Blocked <> 1
ORDER BY FName, SName 
LIMIT  ?, 10

Table is created as follows:

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;

Explain gives the following:

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

Add index (Blocked, FName, SName)
And change where to Blocked = 0 , if it is possible

If you want optimize this query you could create an index on the field in where condition

CREATE INDEX id_users_blocked ON users (Blocked) ;

the optimization depend by the number of users withBlocked <> 1

If these are few don't aspect particolar improvement .. but in explain you don't shoudl see All.

You can also add fname, sname in index field but the use of trim for a way and the need of the field pic can't make this index performant .. because if the firsta case the fields normally with function like trim are not get from index and in the second is not gooe an index with a field like pic .. so the access at the table row is mandatory.

SELECT UserID, TRIM(FName) AS FName, TRIM(SName) as SName, pic
FROM users WHERE Blocked <> 1
ORDER BY FName, SName 
LIMIT  ?, 10

Let's analyze your query. You've used clause WHERE to extract values of column Blocked with value <> 1 . Improving this clause depends on data distribution of values in the column Blocked . If only small part of data contains values

blocked <> 1

using INDEX on column blocked will give to you performance increase. In another case INDEX will not help to you.

You have also used TRIM function for each record of your table. If you removed it you will increase performance.

Off course, sort will also affect on query performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM