简体   繁体   中英

How can I improve my simple mysql query speed

I have a very simple query that keeps cropping up in my slow query log. When it crops up it typically says the query took about 3-6 seconds. Here is the query:

UPDATE company_users 
SET isonline=1, last_logon='2011-12-05 19:37:11', last_message=-1, 
    last_signal=-1, location=-1 
WHERE userid='3546600442XXXXX';

I have to use the userid comparison as that is the information I have at the time of the update.

The database structure is:

Field   Type    Null    Key Default Extra
id      int(11) NO  PRI \N  auto_increment
userid  varchar(20) NO  MUL     
version varchar(3)  YES     37  
owneruserid int(11) NO  MUL 0   
simcard_phonenumber varchar(20) YES     \N  
registration_date   date    YES     \N  
labelname   varchar(20) YES     \N  
isonline    smallint(6) YES     0   
last_logon  datetime    YES     \N  
last_message    int(11) YES     0   
last_voltage    int(11) YES     0   
last_reboot datetime    YES     \N      
connect_mode    int(11) YES     1   
scheduleid  int(11) YES MUL -1  
location        int(11) YES MUL -1  
img             varchar(50) YES         

I have indexes of the following:

company_users 0 PRIMARY 1 id A 197 \\N \\N BTREE
company_users 1 indx_userid 1 userid A 197 \\N \\N BTREE
company_users 1 indx_location 1 location A 12 \\N \\N YES BTREE
company_users 1 indx_scheduleid 1 scheduleid A 49 \\N \\N YES BTREE
company_users 1 indx_owneruserid 1 owneruserid A 197 \\N \\N BTREE

The table has about 300 rows in it. The database is on the same server as my website. These queries are run using a PHP script.

Hopefully that is enough info to get some idea of what I might be doing wrong, or where I can tweak my config.

UPDATE: After the suggestion by Dennis I had another look at my slow query log and noticed there were three statements logged against a time frame. This was the info for two of them which were the same type of update statement identified above:

Query_time: 5 Lock_time: 0 Rows_sent: 0 Rows_examined: 0

Query_time: 5 Lock_time: 0 Rows_sent: 0 Rows_examined: 0

Query_time: 4 Lock_time: 0 Rows_sent: 1 Rows_examined: 1

This last was for a select on the same table. I did an analyze on the select statement (as I didn't know how to do that on an Update) and it showed:

id select_type table type possible_keys key key_len ref rows Extra1 SIMPLE company_users const indx_imei indx_imei 22 const 1

Having a lot of indexes can speed up select statements, but slow down inserts, updates, and deletes. My first suggestion would be to remove the indexes and re-execute the queries to see if time is improved.

I would suggest that the problem issue, updating a record on a flat table of 300 records, is not related to the indexes. It sounds like your insert statement is being blocked by another statement . Is it always slow or slow only under certain conditions, this would further make it seem that blocking is the likely candidate. You need more information really. I would investigate possible blocking selects on that table to see if they are a culprit, and see initially if those queries can be optimised before looking at things like the transaction isolation levels and autocommit config.

If the problem is a select query locking you could verify (and possibly solve your issue) by running the select query without locking. This could be done by

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ; -- Place your select query here
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;

However, this approach has some health warnings associated with it. It is a better practice to get more info about what is wrong and solve the offending queries by making them as close as optimal as possible rather than using this approach.

I remember this Coding Horror blog as having some useful insights.

I agree with AlexC that most likely another statement is blocking your UPDATE statement. If you want to make certain your UPDATES are not getting blocked, you could work with two databases. On the master db you do your UPDATES and INSERTS and the second, which is replicated from the first, is where all the SELECTing is happening.

Alternatively, you could certainly figure out what statements are actually blocking your query and try optimizing them. On a heavily selected database this might not be easily achievable.

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