假設我有一張桌子:
create table any_table (any_column_1 int, any_column_2 varchar(255));
create index any_table_any_column_1_IDX USING BTREE ON any_table (any_column_1);
(注意:索引型別在這里應該無關緊要)
我想知道是否查詢或對性能any_column有任何影響,即intstring
select * from any_table where any_column_1 = 12345;
和這個在性能上有什么區別嗎?
select * from any_table where any_column_1 = '12345';
我環顧了網路,真的沒有遇到過這種特殊情況。
uj5u.com熱心網友回復:
對于索引整數列,無論哪種方式都應該沒問題。當您將整數列與常量進行比較時,無論您將其格式化為整數還是字串,都會將常量值轉換為整數。
您可以通過 EXPLAIN 確認這一點。在這兩種情況下,EXPLAIN 都表明它將使用索引(type: ref表示索引查找),并且性能相同。
mysql> explain select * from any_table where any_column_1 = 12345;
---- ------------- ----------- ------------ ------ ---------------------------- ---------------------------- --------- ------- ------ ---------- -------
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---- ------------- ----------- ------------ ------ ---------------------------- ---------------------------- --------- ------- ------ ---------- -------
| 1 | SIMPLE | any_table | NULL | ref | any_table_any_column_1_IDX | any_table_any_column_1_IDX | 5 | const | 1 | 100.00 | NULL |
---- ------------- ----------- ------------ ------ ---------------------------- ---------------------------- --------- ------- ------ ---------- -------
mysql> explain select * from any_table where any_column_1 = '12345';
---- ------------- ----------- ------------ ------ ---------------------------- ---------------------------- --------- ------- ------ ---------- -------
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---- ------------- ----------- ------------ ------ ---------------------------- ---------------------------- --------- ------- ------ ---------- -------
| 1 | SIMPLE | any_table | NULL | ref | any_table_any_column_1_IDX | any_table_any_column_1_IDX | 5 | const | 1 | 100.00 | NULL |
---- ------------- ----------- ------------ ------ ---------------------------- ---------------------------- --------- ------- ------ ---------- -------
如果您在示例中為字串列編制了索引any_column_2,則會有所不同,因為字串列的排序規則必須與您與之比較的值的排序規則相匹配。默認情況下,字串文字將被轉換為兼容的排序規則,因此它使用索引:
create index any_table_any_column_2_IDX USING BTREE ON any_table (any_column_2);
mysql> explain select * from any_table where any_column_2 = '12345';
---- ------------- ----------- ------------ ------ ---------------------------- ---------------------------- --------- ------- ------ ---------- -------
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---- ------------- ----------- ------------ ------ ---------------------------- ---------------------------- --------- ------- ------ ---------- -------
| 1 | SIMPLE | any_table | NULL | ref | any_table_any_column_2_IDX | any_table_any_column_2_IDX | 768 | const | 1 | 100.00 | NULL |
---- ------------- ----------- ------------ ------ ---------------------------- ---------------------------- --------- ------- ------ ---------- -------
但是整數文字沒有排序規則,因此您會收到警告,并且無法使用索引。EXPLAIN 顯示type: ALL,因此它將執行表掃描,如果您查詢包含許多行的表,則性能會很差。
mysql> explain select * from any_table where any_column_2 = 12345;
---- ------------- ----------- ------------ ------ ---------------------------- ------ --------- ------ ------ ---------- -------------
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
---- ------------- ----------- ------------ ------ ---------------------------- ------ --------- ------ ------ ---------- -------------
| 1 | SIMPLE | any_table | NULL | ALL | any_table_any_column_2_IDX | NULL | NULL | NULL | 1 | 100.00 | Using where |
---- ------------- ----------- ------------ ------ ---------------------------- ------ --------- ------ ------ ---------- -------------
1 row in set, 3 warnings (0.00 sec)
mysql> show warnings;
--------- ------ -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Level | Code | Message |
--------- ------ -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Warning | 1739 | Cannot use ref access on index 'any_table_any_column_2_IDX' due to type or collation conversion on field 'any_column_2' |
| Warning | 1739 | Cannot use range access on index 'any_table_any_column_2_IDX' due to type or collation conversion on field 'any_column_2' |
| Note | 1003 | /* select#1 */ select `test2`.`any_table`.`any_column_1` AS `any_column_1`,`test2`.`any_table`.`any_column_2` AS `any_column_2` from `test2`.`any_table` where (`test2`.`any_table`.`any_column_2` = 12345) |
--------- ------ -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/474807.html
標籤:mysql
下一篇:LEFTJOIN只回傳第一行
