Rumah pangkalan data tutorial mysql 类型转换对MySQL选择索引的影响_MySQL

类型转换对MySQL选择索引的影响_MySQL

Jun 01, 2016 pm 01:44 PM
Pengaruh

bitsCN.com

遇到了几例 MySQL 没用使用预期索引的问题,读了些文档之后,发现 MySQL 的类型转换对索引选择的影响还真是一个不大不小的坑。

比如有这样一张 MySQL 表:

CREATE TABLE `indextest` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
`age` tinyint(3) unsigned NOT NULL DEFAULT ’0′,
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_name` (`name`),
KEY `idx_age` (`age`),
KEY `idx_create` (`create_time`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1

name 是一个有索引的 varchar 字段,表内数据是这样的:

+—-+——–+—–+———————+
| id | name | age | create_time |
+—-+——–+—–+———————+
| 1 | hello | 10 | 2012-02-01 20:00:00 |
| 2 | world | 20 | 2012-02-02 20:00:00 |
| 3 | 111222 | 30 | 2012-02-03 20:00:00 |
| 4 | wow | 40 | 2012-02-04 20:00:00 |
+—-+——–+—–+———————+

使用字符串 ’111222′ 作为参数对 name 字段查询,Execution Plan 如预期的一样,会使用 name 字段上的索引 idx_name:

mysql [localhost] {msandbox} (test) > explain select age from
-> indextest where name=’111222′/G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: indextest
type: ref
possible_keys: idx_name
key: idx_name
key_len: 13
ref: const
rows: 1
Extra: Using where
1 row in set (0.00 sec)

而使用数字作为参数对 name 字段做查询时,explain 表明这将是全表扫描:

mysql [localhost] {msandbox} (test) > explain select age from
-> indextest where name=111222/G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: indextest
type: ALL
possible_keys: idx_name
key: NULL
key_len: NULL
ref: NULL
rows: 4
Extra: Using where
1 row in set (0.00 sec)

究其原因,是当文本字段与数字进行比较时,由于类型不同,MySQL 需要做隐式类型转换才能进行比较,结果就如上面的例子所提到的一样。

MySQL 的文档 (Type Conversion in Expression Evaluation) 中提到,在做比较时,会按这样的规则进行必要的类型转换:

两个参数至少有一个是 NULL 时,比较的结果也是 NULL,例外是使用 对两个 NULL 做比较时会返回 1,这两种情况都不需要做类型转换
两个参数都是字符串,会按照字符串来比较,不做类型转换
两个参数都是整数,按照整数来比较,不做类型转换
十六进制的值和非数字做比较时,会被当做二进制串,和数字做比较时会按下面的规则处理
有一个参数是 TIMESTAMP 或 DATETIME,并且另外一个参数是常量,常量会被转换为 timestamp
有一个参数是 decimal 类型,如果另外一个参数是 decimal 或者整数,会将整数转换为 decimal 后进行比较,如果另外一个参数是浮点数,则会把 decimal 转换为浮点数进行比较
所有其他情况下,两个参数都会被转换为浮点数再进行比较
比如:

mysql [localhost] {msandbox} (test) > SELECT ’18015376320243459′ =
-> 18015376320243459;
+—————————————–+
| ’18015376320243459′ = 18015376320243459 |
+—————————————–+
| 0 |
+—————————————–+
1 row in set (0.00 sec)

mysql [localhost] {msandbox} (test) > SELECT ’18015376320243459′ + 0;
+————————-+
| ’18015376320243459′ + 0 |
+————————-+
| 1.80153763202435e+16 |
+————————-+
1 row in set (0.00 sec)
mysql [localhost] {msandbox} (test) > SELECT
-> cast(’18015376320243459′ as unsigned) = 18015376320243459;
+———————————————————–+
| cast(’18015376320243459′ as unsigned) = 18015376320243459 |
+———————————————————–+
| 1 |
+———————————————————–+
1 row in set (0.00 sec)

因为浮点数精度(53 bits)问题,并且 MySQL 将字符串转换为浮点数和将整数转换为浮点数使用不同的方法,字符串 ’18015376320243459′ 和整数 18015376320243459 相比较就不相等,如果要避免隐式浮点数转换带来的精度问题,可以显式地使用 cast 做类型转换,将字符串转换为整数。

按照这些规则,对于上面的例子来说,name 字段的值和查询参数 ’111222′ 都会被转换为浮点数才会做比较,而很多文本都能转换为和 111222 相等的数值,比如 ’111222′, ’111222aabb’, ‘ 111222′ 和 ’11122.2e1′,所以 MySQL 不能有效使用索引,就退化为索引扫描甚至是全表扫描。

而反过来,如果使用一个字符串作为查询参数,对一个数字字段做比较查询,MySQL 则是可以有效利用索引的:

mysql [localhost] {msandbox} (test) > explain select name from
-> indextest where age=’30′/G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: indextest
type: ref
possible_keys: idx_age
key: idx_age
key_len: 1
ref: const
rows: 1
Extra:
1 row in set (0.00 sec)

原因则是,MySQL 可以将查询参数 ’30′ 转换为确定的数值 30,之后可以快速地在索引中找到与之相等的数值。

除此之外,使用函数对索引字段做显式类型转换或者计算也会使 MySQL 无法使用索引:

mysql [localhost] {msandbox} (test) > explain select name from
-> indextest where cast(age as unsigned)=30/G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: indextest
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4
Extra: Using where
1 row in set (0.00 sec)

如上,使用 cast 函数对 age 做显式的类型转换,会使索引失效,当然了,在实际的代码中很少会有这样的写法,但类似下面这样对时间字段做运算的用法就比较多了:

mysql [localhost] {msandbox} (test) > explain select * from
-> indextest where date(create_time)=’2012-02-02′/G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: indextest
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4
Extra: Using where
1 row in set (0.00 sec)

对于本例的需求,是想查找 create_time 是 2012-02-02 这一天的记录,用变通的方法,避免在索引字段上做运算就可以有效使用索引了:

mysql [localhost] {msandbox} (test) > explain select * from
-> indextest where create_time between ’2012-02-02′ and ’2012-02-03′/G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: indextest
type: range
possible_keys: idx_create
key: idx_create
key_len: 4
ref: NULL
rows: 1
Extra: Using where
1 row in set (0.00 sec)

MySQL 的 How … 系列文档值得读一读,比如:

  • How MySQL Uses Indexes
  • How MySQL Uses Memory
  • How MySQL Uses Internal Temporary Tables
  • How to Cope with Deadlocks
  • How MySQL Opens and Closes Tables
  • How MySQL Uses Threads for Client Connections
  • How to Determine What is Causing a Problem

伟大开源软件的文档总是需要经过反复阅读,才能逐步被理解和正确运用,RTFM 和 RTFS 的光辉无限

bitsCN.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

VBOX_E_OBJECT_NOT_FOUND(0x80bb0001)Ralat VirtualBox VBOX_E_OBJECT_NOT_FOUND(0x80bb0001)Ralat VirtualBox Mar 24, 2024 am 09:51 AM

Apabila cuba membuka imej cakera dalam VirtualBox, anda mungkin menghadapi ralat yang menunjukkan bahawa cakera keras tidak boleh didaftarkan. Ini biasanya berlaku apabila fail imej cakera VM yang anda cuba buka mempunyai UUID yang sama seperti fail imej cakera maya yang lain. Dalam kes ini, VirtualBox memaparkan kod ralat VBOX_E_OBJECT_NOT_FOUND(0x80bb0001). Jika anda menghadapi ralat ini, jangan risau, terdapat beberapa penyelesaian yang boleh anda cuba. Mula-mula, anda boleh cuba menggunakan alat baris arahan VirtualBox untuk menukar UUID fail imej cakera, yang akan mengelakkan konflik. Anda boleh menjalankan arahan `VBoxManageinternal

Sejauh manakah keberkesanan menerima panggilan telefon menggunakan mod kapal terbang? Sejauh manakah keberkesanan menerima panggilan telefon menggunakan mod kapal terbang? Feb 20, 2024 am 10:07 AM

Apa yang berlaku apabila seseorang menelefon dalam mod pesawat? Telefon bimbit telah menjadi salah satu alat yang sangat diperlukan dalam kehidupan orang ramai, ia bukan sahaja alat komunikasi, tetapi juga koleksi hiburan, pembelajaran, kerja dan fungsi lain. Dengan peningkatan berterusan dan penambahbaikan fungsi telefon mudah alih, orang ramai menjadi semakin bergantung kepada telefon mudah alih. Dengan kemunculan mod kapal terbang, orang ramai boleh menggunakan telefon mereka dengan lebih mudah semasa penerbangan. Walau bagaimanapun, sesetengah orang bimbang tentang kesan panggilan orang lain dalam mod kapal terbang pada telefon mudah alih atau pengguna? Artikel ini akan menganalisis dan membincangkan dari beberapa aspek. pertama

Bagaimana untuk mematikan fungsi ulasan pada TikTok? Apakah yang berlaku selepas mematikan fungsi ulasan pada TikTok? Bagaimana untuk mematikan fungsi ulasan pada TikTok? Apakah yang berlaku selepas mematikan fungsi ulasan pada TikTok? Mar 23, 2024 pm 06:20 PM

Di platform Douyin, pengguna bukan sahaja boleh berkongsi detik hidup mereka, tetapi juga berinteraksi dengan pengguna lain. Kadangkala fungsi ulasan boleh menyebabkan beberapa pengalaman yang tidak menyenangkan, seperti keganasan dalam talian, komen berniat jahat, dsb. Jadi, bagaimana untuk mematikan fungsi ulasan TikTok? 1. Bagaimana untuk mematikan fungsi komen Douyin? 1. Log masuk ke APP Douyin dan masukkan halaman utama peribadi anda. 2. Klik "I" di penjuru kanan sebelah bawah untuk memasuki menu tetapan. 3. Dalam menu tetapan, cari "Tetapan Privasi". 4. Klik "Tetapan Privasi" untuk memasuki antara muka tetapan privasi. 5. Dalam antara muka tetapan privasi, cari "Tetapan Komen". 6. Klik "Tetapan Komen" untuk memasuki antara muka tetapan ulasan. 7. Dalam antara muka tetapan ulasan, cari pilihan "Tutup Komen". 8. Klik pilihan "Tutup Komen" untuk mengesahkan ulasan penutup

Kerentanan Kemasukan Fail di Jawa dan Kesannya Kerentanan Kemasukan Fail di Jawa dan Kesannya Aug 08, 2023 am 10:30 AM

Java ialah bahasa pengaturcaraan yang biasa digunakan untuk membangunkan pelbagai aplikasi. Walau bagaimanapun, sama seperti bahasa pengaturcaraan lain, Java mempunyai kelemahan dan risiko keselamatan. Salah satu kelemahan yang biasa ialah kerentanan kemasukan fail (FileInclusionVulnerability) Artikel ini akan meneroka prinsip, kesan dan cara mencegah kerentanan ini. Kerentanan kemasukan fail merujuk kepada pengenalan dinamik atau kemasukan fail lain dalam program, tetapi fail yang diperkenalkan tidak disahkan dan dilindungi sepenuhnya, oleh itu

Kesan kekurangan data terhadap latihan model Kesan kekurangan data terhadap latihan model Oct 08, 2023 pm 06:17 PM

Kesan kekurangan data pada latihan model memerlukan contoh kod khusus Dalam bidang pembelajaran mesin dan kecerdasan buatan, data ialah salah satu elemen teras untuk model latihan. Walau bagaimanapun, masalah yang sering kita hadapi dalam realiti adalah kekurangan data. Kekurangan data merujuk kepada jumlah data latihan yang tidak mencukupi atau kekurangan data beranotasi Dalam kes ini, ia akan memberi kesan tertentu pada latihan model. Masalah kekurangan data terutamanya dicerminkan dalam aspek-aspek berikut: Overfitting: Apabila jumlah data latihan tidak mencukupi, model terdedah kepada overfitting. Overfitting merujuk kepada model yang terlalu menyesuaikan diri dengan data latihan.

Apakah masalah yang akan ditimbulkan oleh sektor buruk pada cakera keras? Apakah masalah yang akan ditimbulkan oleh sektor buruk pada cakera keras? Feb 18, 2024 am 10:07 AM

Sektor buruk pada cakera keras merujuk kepada kegagalan fizikal cakera keras, iaitu, unit storan pada cakera keras tidak boleh membaca atau menulis data secara normal. Kesan sektor buruk pada cakera keras adalah sangat ketara, dan ia boleh menyebabkan kehilangan data, ranap sistem dan prestasi cakera keras yang berkurangan. Artikel ini akan memperkenalkan secara terperinci kesan sektor buruk cakera keras dan penyelesaian yang berkaitan. Pertama, sektor buruk pada cakera keras boleh menyebabkan kehilangan data. Apabila sektor dalam cakera keras mempunyai sektor buruk, data pada sektor itu tidak boleh dibaca, mengakibatkan kerosakan fail atau tidak boleh diakses. Keadaan ini amat serius jika fail penting disimpan dalam sektor di mana sektor buruk berada.

Apakah kesan khusus kad lombong terhadap permainan? Apakah kesan khusus kad lombong terhadap permainan? Jan 03, 2024 am 09:05 AM

Sesetengah pengguna mungkin mempertimbangkan untuk membeli kad perlombongan demi harga yang murah. Apakah kesan penggunaan kad mining untuk bermain permainan: 1. Kestabilan bermain permainan dengan kad mining tidak dapat dijamin, kerana hayat kad mining adalah sangat singkat dan berkemungkinan menjadi tidak berguna selepas bermain sahaja. 2. Kad perlombongan pada asasnya adalah versi yang dikebiri daripada versi asal Disebabkan haus dan lusuh jangka panjang, prestasi dalam semua aspek mungkin lemah. 3. Dengan cara ini, pengguna mungkin tidak dapat memaparkan semua kesan permainan semasa bermain permainan. 4. Lebih-lebih lagi, komponen elektronik kad grafik akan menua lebih awal, apatah lagi bermain permainan juga memakan kad grafik, jadi ia telah dikeringkan ke tahap yang lebih besar, jadi impak kepada permainan adalah hebat. 5. Secara umumnya, gunakan kad mining untuk bermain permainan

Apakah kesan kebocoran casis pada komputer? Apakah kesan kebocoran casis pada komputer? Feb 22, 2024 pm 06:48 PM

Apakah kesan kebocoran casis terhadap komputer? Dengan kemajuan teknologi yang berterusan, komputer secara beransur-ansur menjadi alat yang sangat diperlukan dalam kehidupan orang ramai, sama ada bekerja, belajar atau hiburan, ia tidak dapat dipisahkan daripada penggunaan komputer. Walau bagaimanapun, sementara kita menikmati kemudahan yang dibawa oleh komputer, kita juga perlu memberi perhatian kepada keselamatannya. Kebocoran kes adalah masalah yang berpotensi yang, jika tidak ditangani tepat pada masanya, mungkin mempunyai kesan serius pada komputer dan pengguna. Pertama sekali, kebocoran casis akan menyebabkan kerosakan pada perkakasan komputer. Papan induk komputer, bekalan kuasa, litar dalaman dan komponen lain semuanya berada di dalam casis

See all articles