简体   繁体   English

如何提高简单的mysql查询速度

[英]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. 当它出现时,通常会说查询大约需要3到6秒。 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. 我必须使用userid比较,因为这是我在更新时所拥有的信息。

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 0主用户1 id A 197 \\ N \\ N BTREE
company_users 1 indx_userid 1 userid A 197 \\N \\N BTREE company_users 1 indx_userid 1用户ID A 197 \\ N \\ N BTREE
company_users 1 indx_location 1 location A 12 \\N \\N YES BTREE company_users 1 indx_location 1位置A 12 \\ N \\ N是BTREE
company_users 1 indx_scheduleid 1 scheduleid A 49 \\N \\N YES BTREE company_users 1 indx_scheduleid 1 scheduleid A 49 \\ N \\ N是BTREE
company_users 1 indx_owneruserid 1 owneruserid A 197 \\N \\N BTREE company_users 1 indx_owneruserid 1 owneruserid A 197 \\ N \\ N BTREE

The table has about 300 rows in it. 该表中约有300行。 The database is on the same server as my website. 该数据库与我的网站位于同一服务器上。 These queries are run using a PHP script. 这些查询使用PHP脚本运行。

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 查询时间:5锁定时间:0发送的行数:0已检查的行数:0

Query_time: 5 Lock_time: 0 Rows_sent: 0 Rows_examined: 0 查询时间:5锁定时间:0发送的行数:0已检查的行数:0

Query_time: 4 Lock_time: 0 Rows_sent: 1 Rows_examined: 1 查询时间:4锁定时间:0发送的行数:1已检查的行数: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: 我对select语句进行了分析(因为我不知道如何在Update上执行该操作),结果显示:

id select_type table type possible_keys key key_len ref rows Extra1 SIMPLE company_users const indx_imei indx_imei 22 const 1 id select_type表的类型possible_keys键key_len ref行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. 我建议问题问题(在300条记录的平面表上更新一条记录)与索引无关。 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. 我记得这个Coding Horror博客具有一些有用的见解。

I agree with AlexC that most likely another statement is blocking your UPDATE statement. 我同意AlexC的说法,很可能是另一条语句阻止了您的UPDATE语句。 If you want to make certain your UPDATES are not getting blocked, you could work with two databases. 如果要确保未阻止UPDATE,则可以使用两个数据库。 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. 在主数据库上,执行UPDATES和INSERTS,第二个是从第一个复制的,它是所有SELECTING发生的地方。

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. 在大量选择的数据库上,这可能不容易实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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