Rumah pangkalan data tutorial mysql MySQL前缀索引导致的慢查询_MySQL

MySQL前缀索引导致的慢查询_MySQL

Jun 01, 2016 pm 01:34 PM
mysql projek

bitsCN.com

前端时间跟一个DB相关的项目,alanc反馈有一个查询,使用索引比不使用索引慢很多倍,有点毁三观。所以跟进了一下,用explain,看了看2个查询不同的结果。

不用索引的查询的时候结果如下,实际查询中速度比较块。

mysql> explain select * from rosterusers limit 10000,3 ;

+----+-------------+-------------+------+---------------+------+---------+------+---------+-------+
| id | select_type | table       | type | possible_keys | key  | key_len | ref  | rows    | Extra |
+----+-------------+-------------+------+---------------+------+---------+------+---------+-------+
|  1 | SIMPLE      | rosterusers | ALL  | NULL          | NULL | NULL    | NULL | 2010066 |       |
+----+-------------+-------------+------+---------------+------+---------+------+---------+-------+

 

 

而使用索引order by的查询结果如下,速度反而慢的惊人。

mysql> explain select * from rosterusers order by username limit 10000,3 ;

+----+-------------+-------------+------+---------------+------+---------+------+---------+----------------+
| id | select_type | table       | type | possible_keys | key  | key_len | ref  | rows    | Extra          |
+----+-------------+-------------+------+---------------+------+---------+------+---------+----------------+
|  1 | SIMPLE      | rosterusers | ALL  | NULL          | NULL | NULL    | NULL | 2010087 | Using filesort |
+----+-------------+-------------+------+---------------+------+---------+------+---------+----------------+

 

区别在于,使用索引查询的Extra变成了,Using filesort。居然用了使用外部文件进行排序。这个当然慢了。

但数据表上在username,的确是有索引的。怎么会反而要Using filesort?

看了一下数据表定义。是一个开源聊天服务器ejabberd的一张表。初看以为主键i_rosteru_user_jid是username,和jid的联合索引,那么使用order by username时应该是可以使用到索引才对呀?

CREATE TABLE `rosterusers` (

`username` varchar(250) NOT NULL,

`jid` varchar(250) NOT NULL,

UNIQUE KEY `i_rosteru_user_jid` (`username`(75),`jid`(75)),

KEY `i_rosteru_jid` (`jid`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

仔细检查突然发现其主键定义,不是定义的完整的主键名称,而跟了一个75的长度描述,稍稍一愣,原来用的是前缀索引,而不是整个字段都是索引。(我的记忆里面InnoDB还不支持这玩意,估计是4.0后什么版本加入的),前缀索引就是将数据字段中前面N个字节作为索引的一种方式。。

发现了这个问题后,我们开始怀疑慢查询和这个索引有关,前缀索引的主要用途在于有时字段过程,而MySQL支持的很多索引长度是有限制的。

首先不带order by 的limit 这种查询,本质可能还是和主键相关的,因为MySQL 的INNODB的操作实际都是依靠主键的(即使你没有建立,系统也会有一个默认的),而limit这种查询,使用主键是可以加快速度,(explain返回的rows 应该是一个参考值),虽然我没有看见什么文档明确的说明过这个问题,但从不带order by 的limit 查询的返回结果基本可以证明这点。

但当我们使用order by username的时候,由于希望使用的是username的排序,而不是username(75)的排序,但实际索引是前缀索引,不是完整字段的索引。所以反而导致了order by的时候完全无法利用索引了。(我在SQL语句里面增加强制使用索引i_rosteru_user_jid也不起作用)。而其实使用中,表中的字段username 连75个都用不到,何况定义的250的长度。完全是自己折腾导致的麻烦。由于这是其他产品的表格,我们无法更改,暂时只能先将就用不不带排序的查询讲究。

总结:

  • 前缀索引,并不是一个万能药,他的确可以帮助我们对一个写过长的字段上建立索引。但也会导致排序(order by ,group by)查询上都是无法使用前缀索引的。
  • 任何时候,对于DB Schema定义,合理的规划自己的字段长度,字段类型都是首要的事情。

【本文作者是雁渡寒潭,本着自由的精神,你可以在无盈利的情况完整转载此文档,转载时请附上BLOG链接:http://www.cnblogs.com/fullsail/ 或者http://blog.csdn.net/fullsail,否则每字一元,每图一百不讲价。

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

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

Repo: Cara menghidupkan semula rakan sepasukan
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌

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)

Kemahiran pemprosesan struktur data besar PHP Kemahiran pemprosesan struktur data besar PHP May 08, 2024 am 10:24 AM

Kemahiran pemprosesan struktur data besar: Pecahan: Pecahkan set data dan proseskannya dalam bahagian untuk mengurangkan penggunaan memori. Penjana: Hasilkan item data satu demi satu tanpa memuatkan keseluruhan set data, sesuai untuk set data tanpa had. Penstriman: Baca fail atau hasil pertanyaan baris demi baris, sesuai untuk fail besar atau data jauh. Storan luaran: Untuk set data yang sangat besar, simpan data dalam pangkalan data atau NoSQL.

Bagaimana untuk mengoptimumkan prestasi pertanyaan MySQL dalam PHP? Bagaimana untuk mengoptimumkan prestasi pertanyaan MySQL dalam PHP? Jun 03, 2024 pm 08:11 PM

Prestasi pertanyaan MySQL boleh dioptimumkan dengan membina indeks yang mengurangkan masa carian daripada kerumitan linear kepada kerumitan logaritma. Gunakan PreparedStatements untuk menghalang suntikan SQL dan meningkatkan prestasi pertanyaan. Hadkan hasil pertanyaan dan kurangkan jumlah data yang diproses oleh pelayan. Optimumkan pertanyaan penyertaan, termasuk menggunakan jenis gabungan yang sesuai, membuat indeks dan mempertimbangkan untuk menggunakan subkueri. Menganalisis pertanyaan untuk mengenal pasti kesesakan; gunakan caching untuk mengurangkan beban pangkalan data;

Bagaimana untuk menggunakan sandaran dan pemulihan MySQL dalam PHP? Bagaimana untuk menggunakan sandaran dan pemulihan MySQL dalam PHP? Jun 03, 2024 pm 12:19 PM

Membuat sandaran dan memulihkan pangkalan data MySQL dalam PHP boleh dicapai dengan mengikuti langkah berikut: Sandarkan pangkalan data: Gunakan arahan mysqldump untuk membuang pangkalan data ke dalam fail SQL. Pulihkan pangkalan data: Gunakan arahan mysql untuk memulihkan pangkalan data daripada fail SQL.

Bagaimana untuk memasukkan data ke dalam jadual MySQL menggunakan PHP? Bagaimana untuk memasukkan data ke dalam jadual MySQL menggunakan PHP? Jun 02, 2024 pm 02:26 PM

Bagaimana untuk memasukkan data ke dalam jadual MySQL? Sambung ke pangkalan data: Gunakan mysqli untuk mewujudkan sambungan ke pangkalan data. Sediakan pertanyaan SQL: Tulis pernyataan INSERT untuk menentukan lajur dan nilai yang akan dimasukkan. Laksanakan pertanyaan: Gunakan kaedah query() untuk melaksanakan pertanyaan sisipan Jika berjaya, mesej pengesahan akan dikeluarkan.

Bagaimana untuk membetulkan ralat mysql_native_password tidak dimuatkan pada MySQL 8.4 Bagaimana untuk membetulkan ralat mysql_native_password tidak dimuatkan pada MySQL 8.4 Dec 09, 2024 am 11:42 AM

Salah satu perubahan utama yang diperkenalkan dalam MySQL 8.4 (keluaran LTS terkini pada 2024) ialah pemalam "Kata Laluan Asli MySQL" tidak lagi didayakan secara lalai. Selanjutnya, MySQL 9.0 mengalih keluar pemalam ini sepenuhnya. Perubahan ini mempengaruhi PHP dan apl lain

Bagaimana untuk menggunakan prosedur tersimpan MySQL dalam PHP? Bagaimana untuk menggunakan prosedur tersimpan MySQL dalam PHP? Jun 02, 2024 pm 02:13 PM

Untuk menggunakan prosedur tersimpan MySQL dalam PHP: Gunakan PDO atau sambungan MySQLi untuk menyambung ke pangkalan data MySQL. Sediakan penyata untuk memanggil prosedur tersimpan. Laksanakan prosedur tersimpan. Proses set keputusan (jika prosedur tersimpan mengembalikan hasil). Tutup sambungan pangkalan data.

Bagaimana untuk membuat jadual MySQL menggunakan PHP? Bagaimana untuk membuat jadual MySQL menggunakan PHP? Jun 04, 2024 pm 01:57 PM

Mencipta jadual MySQL menggunakan PHP memerlukan langkah berikut: Sambung ke pangkalan data. Buat pangkalan data jika ia tidak wujud. Pilih pangkalan data. Buat jadual. Laksanakan pertanyaan. Tutup sambungan.

Perbezaan antara pangkalan data oracle dan mysql Perbezaan antara pangkalan data oracle dan mysql May 10, 2024 am 01:54 AM

Pangkalan data Oracle dan MySQL adalah kedua-dua pangkalan data berdasarkan model hubungan, tetapi Oracle lebih unggul dari segi keserasian, skalabiliti, jenis data dan keselamatan manakala MySQL memfokuskan pada kelajuan dan fleksibiliti dan lebih sesuai untuk set data bersaiz kecil. ① Oracle menyediakan pelbagai jenis data, ② menyediakan ciri keselamatan lanjutan, ③ sesuai untuk aplikasi peringkat perusahaan ① MySQL menyokong jenis data NoSQL, ② mempunyai langkah keselamatan yang lebih sedikit, dan ③ sesuai untuk aplikasi bersaiz kecil hingga sederhana.

See all articles