简体   繁体   English

简单查询导致数据库CPU使用率高

[英]Simple query causing high database CPU usage

I have the following simple MySQL query: 我有以下简单的MySQL查询:

SELECT COUNT(*) FROM images WHERE path LIKE '%/path/to/image.jpg'

The field path has an index. 字段path具有索引。 Table has about 500,000 records. 表有大约500,000条记录。

Although the query takes less than a millisecond to execute, I am watching the CPU usage for MySQL ratchet higher and higher in the process list even though this is the only query. 尽管查询执行不到一毫秒,但我正在监视进程列表中MySQL棘轮的CPU使用率,尽管这是唯一的查询。 Eventually it climbs to 99%. 最终,它攀升至99%。

The only other thing the script does is increment a simple counter and then delete a file if the corresponding entry doesn't exist in the database. 该脚本唯一要做的另一件事就是增加一个简单的计数器,然后在数据库中不存在相应条目的情况下删除文件。

The PHP code itself only uses a tiny bit of the CPU (0.3%) according to profiling. 根据性能分析,PHP代码本身仅占用一小部分CPU(0.3%)。

I tried dropping it down to only do the first 5,000, but the script never finishes. 我尝试将其降低到仅执行前5,000个,但脚本从未完成。 I just see a blank page despite buffer flushes that are supposed to show me the progress every 25 records. 尽管缓冲区刷新应该每25条记录向我显示进度,但我只是看到一个空白页。

What could cause this sort of MySQL CPU usage increase over the same sort of super simple query? 是什么原因会导致这种MySQL CPU使用率超过同类超级简单查询?

The field path has an index. 字段路径具有索引。

The index is useless for such a query. 索引对于此类查询没有用。 Btree indexes can only be used with LIKE when the LIKE argument contains variable postfix ( LIKE 'something%' ). 仅当LIKE参数包含变量后缀( LIKE 'something%' )时,才可以将Btree索引与LIKE一起使用。 They are not used with variable prefixes ( LIKE '%something' ). 它们不与可变前缀一起使用(如LIKE '%something' )。 You can check the EXPLAIN your_query_here , there you will see that the query uses full table scan. 您可以检查EXPLAIN your_query_here ,在那里您将看到查询使用全表扫描。

So the answer is, your MySQL eats CPU searching through the table (it's likely the table fits entirely in memory, so it's still pretty fast). 因此,答案是,您的MySQL在表中消耗了CPU的搜索量(表可能完全适合内存,因此仍然非常快)。

This kind of query is not simple for server at all. 对于服务器而言,这种查询并不简单。 In your case it is performed fast exactly because it utilizes full available CPU time. 在您的情况下,由于它会利用所有可用的CPU时间,因此执行速度很快。

Consider splitting the 'path' field to path and filename separately, it would allow indexing the filename and performing search by it without having variable postfixes or prefixes, in hope that it will reduce the number of records that the search by path will be performed on. 考虑将“ path”字段分别拆分为path和filename,这将允许为文件名建立索引并通过其执行搜索,而无需使用可变的后缀或前缀,以期希望减少按路径进行搜索的记录数量。

You should use LOCATE instead: 您应该改为使用LOCATE

... WHERE LOCATE('/path/to/image.jpg', path)

This will use your index where LIKE '%...' will not. 这将使用您的索引,而不会使用LIKE '%...'

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

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