This article mainly introduces the relevant information on the index and FROM_UNIXTIME issues in mysql. Friends who need it can refer to it. I hope it can help everyone.
Zero, background
After simply collecting some information, I found that this slow query problem is deeply hidden. After asking many people, including the DBA, I still don’t know the reason.
1. Problem
There is a DB with a field defined as follows.
MySQL [d_union_stat]> desc t_local_cache_log_meta; +----------------+--------------+------+-----+---------------------+ | Field | Type | Null | Key | Default | +----------------+--------------+------+-----+---------------------+ | c_id | int(11) | NO | PRI | NULL | | c_key | varchar(128) | NO | MUL | | | c_time | int(11) | NO | MUL | 0 | | c_mtime | varchar(45) | NO | MUL | 0000-00-00 00:00:00 | +----------------+--------------+------+-----+---------------------+ 17 rows in set (0.01 sec)
The index is as follows:
MySQL [d_union_stat]> show index from t_local_cache_log_meta \G *************************** 1. row *************************** Table: t_local_cache_log_meta Non_unique: 0 Key_name: PRIMARY Column_name: c_id Collation: A Cardinality: 6517096 Index_type: BTREE *************************** 2. row *************************** . . . *************************** 6. row *************************** Table: t_local_cache_log_meta Non_unique: 1 Key_name: index_mtime Column_name: c_mtime Collation: A Cardinality: 592463 Index_type: BTREE 6 rows in set (0.02 sec)
Then I wrote a SQL as follows:
SELECT count(*) FROM d_union_stat.t_local_cache_log_meta where `c_mtime` < FROM_UNIXTIME(1494485402);
Finally one day the DBA came over and gave me a report, saying that this SQL was slow SQL.
# Time: 170518 11:31:14 # Query_time: 12.312329 Lock_time: 0.000061 Rows_sent: 0 Rows_examined: 5809647 SET timestamp=1495078274; DELETE FROM `t_local_cache_log_meta` WHERE `c_mtime`< FROM_UNIXTIME(1494473461) limit 1000;
I was speechless. My DB is indexed and SQL is carefully optimized. Why is SQL slow?
When asked why it is slow SQL, the DBA couldn’t answer it. Even the colleagues around me couldn’t answer it.
I secretly thought that I had encountered a deeply hidden knowledge point.
There are two suspicious places: 1. There are 6 indexes. 2. The rvalue is the FROM_UNIXTIME function.
So I checked the official MYSQL documentation and found that 6 were not problems.
All storage engines support at least 16 indexes per table and a total index length of at least 256 bytes.
Most storage engines have higher limits.
So I suspect the problem is FROM_UNIXTIME function.
Then look at the INDEX section of MYSQL and find some clues.
1.To find the rows matching a WHERE clause quickly.
2. To eliminate rows from consideration.
If there is a choice between multiple indexes, MySQL normally uses the index that finds the smallest number of rows.
3.If the table has a multiple-column index, any leftmost prefix of the index can be used by the optimizer to look up rows.
4. MySQL can use indexes on columns more efficiently if they are declared as the same type and size.
Comparison of dissimilar columns (comparing a string column to a temporal or numeric column, for example) may prevent use of indexes if values cannot be compared directly without conversion.
When I saw Article 4, it was mentioned that different types may lead to no indexing. Could it be that the return value of FROM_UNIXTIME cannot be converted into a string type?
So query the return value of the FROM_UNIXTIME function.
MySQL FROM_UNIXTIME() returns a date /datetime from a version of unix_timestamp.
The return is a time type, which is forced to be converted to a string type Woolen cloth?
MySQL [d_union_stat]> explain SELECT -> * -> FROM -> t_local_cache_log_meta -> where -> `c_mtime` = CONCAT(FROM_UNIXTIME(1494485402)) \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t_local_cache_log_meta type: ref possible_keys: index_mtime key: index_mtime key_len: 137 ref: const rows: 1 Extra: Using where 1 row in set (0.01 sec)
This time you can see that the index is used and only one piece of data is scanned.
2. Conclusion
This time, you can use the index by forcing the return value of FROM_UNIXTIME to be converted.
So this SQL cannot use the upper index because the types of rvalues and lvalues are inconsistent. .
Related recommendations:
MySQL partition field Is it necessary to create a separate index for the column?
Introduction to the method of viewing, creating and deleting indexes in MySQL
The above is the detailed content of Detailed explanation of index and FROM_UNIXTIME issues in mysql. For more information, please follow other related articles on the PHP Chinese website!