日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

知识点:Mysql 数据库索引优化实战(4)

發(fā)布時(shí)間:2023/12/20 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 知识点:Mysql 数据库索引优化实战(4) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

知識(shí)點(diǎn):Mysql 索引原理完全手冊(cè)(1)

知識(shí)點(diǎn):Mysql 索引原理完全手冊(cè)(2)

知識(shí)點(diǎn):Mysql 索引優(yōu)化實(shí)戰(zhàn)(3)

知識(shí)點(diǎn):Mysql 數(shù)據(jù)庫(kù)索引優(yōu)化實(shí)戰(zhàn)(4)

一:插入訂單

業(yè)務(wù)邏輯:插入訂單數(shù)據(jù),為了避免重復(fù)導(dǎo)單,一般會(huì)通過(guò)交易號(hào)去數(shù)據(jù)庫(kù)中查詢,判斷該訂單是否已經(jīng)存在。

最基礎(chǔ)的sql語(yǔ)句

mysql> select * from book_order where order_id = "10000"; +-------+--------------------+-------+------+----------+--------------+----------+------------------+-------------+-------------+------------+---------------------+ | id | order_id | general | net | stock_id | order_status | description | finance_desc | create_type | order_state | creator | create_time | +-------+--------------------+-------+------+----------+--------------+----------+------------------+-------------+-------------+------------+---------------------+ | 10000 | 10000 | 6.6 | 6.13 | 1 | 10 | ok | ok | auto | 1 | itdragon | 2018-06-18 17:01:52 | +-------+--------------------+-------+------+----------+--------------+----------+------------------+-------------+-------------+------------+---------------------+ mysql> explain select * from book_order where order_id = "10000"; +----+-------------+---------------------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------------------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | book_order | NULL | ALL | NULL | NULL | NULL | NULL | 3 | 33.33 | Using where | +----+-------------+---------------------+------------+------+---------------+------+---------+------+------+----------+-------------+

幾百上千萬(wàn)的訂單,全表掃描!

通過(guò)explain命令可以清楚MySQL是如何處理sql語(yǔ)句的。打印的內(nèi)容分別表示:

  • id : 查詢序列號(hào)為1。
  • select_type : 查詢類(lèi)型是簡(jiǎn)單查詢,簡(jiǎn)單的select語(yǔ)句沒(méi)有union和子查詢。
  • table : 表是 book_order。
  • partitions : 沒(méi)有分區(qū)。
  • type : 連接類(lèi)型,all表示采用全表掃描的方式。
  • possible_keys : 可能用到索引為null。
  • key : 實(shí)際用到索引是null。
  • key_len : 索引長(zhǎng)度當(dāng)然也是null。
  • ref : 沒(méi)有哪個(gè)列或者參數(shù)和key一起被使用。
  • Extra : 使用了where查詢。

是type為ALL,全表掃描,假設(shè)數(shù)據(jù)庫(kù)中有幾百萬(wàn)條數(shù)據(jù),在沒(méi)有索引的幫助下會(huì)異常卡頓。

初步優(yōu)化:為order_id創(chuàng)建索引

mysql> create unique index idx_order_transaID on book_order (order_id); mysql> explain select * from book_order where order_id = "10000"; +----+-------------+---------------------+------------+-------+--------------------+--------------------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------------------+------------+-------+--------------------+--------------------+---------+-------+------+----------+-------+ | 1 | SIMPLE | book_order | NULL | const | idx_order_transaID | idx_order_transaID | 453 | const | 1 | 100 | NULL | +----+-------------+---------------------+------------+-------+--------------------+--------------------+---------+-------+------+----------+-------+

這里創(chuàng)建的索引是唯一索引,而非普通索引。

唯一索引打印的type值是const。表示通過(guò)索引一次就可以找到。即找到值就結(jié)束掃描返回查詢結(jié)果。

普通索引打印的type值是ref。表示非唯一性索引掃描。找到值還要繼續(xù)掃描,直到將索引文件掃描完為止。(這里沒(méi)有貼出代碼),顯而易見(jiàn),const的性能要遠(yuǎn)高于ref。并且根據(jù)業(yè)務(wù)邏輯來(lái)判斷,創(chuàng)建唯一索引是合情合理的。

再次優(yōu)化:覆蓋索引

mysql> explain select order_id from book_order where order_id = "10000"; +----+-------------+---------------------+------------+-------+--------------------+--------------------+---------+-------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------------------+------------+-------+--------------------+--------------------+---------+-------+------+----------+-------------+ | 1 | SIMPLE | book_order | NULL | const | idx_order_transaID | idx_order_transaID | 453 | const | 1 | 100 | Using index | +----+-------------+---------------------+------------+-------+--------------------+--------------------+---------+-------+------+----------+-------------+

這里將select * from改為了select order_id from后,Extra 顯示 Using index,表示該查詢使用了覆蓋索引,說(shuō)明該sql語(yǔ)句的性能很好。若提示的是Using filesort(使用內(nèi)部排序)和Using temporary(使用臨時(shí)表)則表明該sql需要立即優(yōu)化了。

根據(jù)業(yè)務(wù)邏輯來(lái)的,查詢結(jié)構(gòu)返回order_id 是可以滿足業(yè)務(wù)邏輯要求的。

二:查詢訂單

業(yè)務(wù)邏輯:優(yōu)先處理訂單級(jí)別高,錄入時(shí)間長(zhǎng)的訂單。

通過(guò)訂單級(jí)別和訂單錄入時(shí)間排序

最基礎(chǔ)的sql語(yǔ)句

mysql> explain select * from book_order order by order_state,create_time; +----+-------------+---------------------+------------+------+---------------+------+---------+------+------+----------+----------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------------------+------------+------+---------------+------+---------+------+------+----------+----------------+ | 1 | SIMPLE | book_order | NULL | ALL | NULL | NULL | NULL | NULL | 3 | 100 | Using filesort | +----+-------------+---------------------+------------+------+---------------+------+---------+------+------+----------+----------------+

首先,采用全表掃描就不合理,還使用了文件排序Using filesort,更加拖慢了性能。 MySQL在4.1版本之前文件排序是采用雙路排序的算法,由于兩次掃描磁盤(pán),I/O耗時(shí)太長(zhǎng)。后優(yōu)化成單路排序算法。其本質(zhì)就是用空間換時(shí)間,但如果數(shù)據(jù)量太大,buffer的空間不足,會(huì)導(dǎo)致多次I/O的情況。其效果反而更差。與其找運(yùn)維同事修改MySQL配置,還不如自己乖乖地建索引。

初步優(yōu)化:為order_state,create_time 創(chuàng)建復(fù)合索引

mysql> create index idx_order_stateDate on book_order (order_state,create_time); mysql> explain select * from book_order order by order_state,create_time; +----+-------------+---------------------+------------+------+---------------+------+---------+------+------+----------+----------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------------------+------------+------+---------------+------+---------+------+------+----------+----------------+ | 1 | SIMPLE | book_order | NULL | ALL | NULL | NULL | NULL | NULL | 3 | 100 | Using filesort | +----+-------------+---------------------+------------+------+---------------+------+---------+------+------+----------+----------------+

創(chuàng)建復(fù)合索引后你會(huì)驚奇的發(fā)現(xiàn),和沒(méi)創(chuàng)建索引一樣???都是全表掃描,都用到了文件排序。是索引失效?還是索引創(chuàng)建失敗?

我們?cè)囍纯聪旅娲蛴∏闆r

mysql> explain select order_state,create_time from book_order order by order_state,create_time; +----+-------------+---------------------+------------+-------+---------------+---------------------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------------------+------------+-------+---------------+---------------------+---------+------+------+----------+-------------+ | 1 | SIMPLE | book_order | NULL | index | NULL | idx_order_stateDate | 68 | NULL | 3 | 100 | Using index | +----+-------------+---------------------+------------+-------+---------------+---------------------+---------+------+------+----------+-------------+

將select * from 換成了 select order_state,create_time from 后。type從all升級(jí)為index,表示(full index scan)全索引文件掃描,Extra也顯示使用了覆蓋索引??墒遣粚?duì)啊!!!!檢索雖然快了,但返回的內(nèi)容只有order_state和create_time 兩個(gè)字段,讓業(yè)務(wù)同事怎么用?難道把每個(gè)字段都建一個(gè)復(fù)合索引?

MySQL沒(méi)有這么笨,可以使用force index 強(qiáng)制指定索引。在原來(lái)的sql語(yǔ)句上修改 force index(idx_order_stateDate) 即可。

mysql> explain select * from book_order force index(idx_order_stateDate) order by order_state,create_time; +----+-------------+---------------------+------------+-------+---------------+---------------------+---------+------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------------------+------------+-------+---------------+---------------------+---------+------+------+----------+-------+ | 1 | SIMPLE | book_order | NULL | index | NULL | idx_order_stateDate | 68 | NULL | 3 | 100 | NULL | +----+-------------+---------------------+------------+-------+---------------+---------------------+---------+------+------+----------+-------+

再次優(yōu)化:訂單級(jí)別真的要排序么?

對(duì)于這種重復(fù)且分布平均的字段,排序和加索引的作用不大。

我們能否先固定 order_state 的值,然后再給 create_time 排序?

mysql> explain select * from book_order where order_state=3 order by create_time; +----+-------------+---------------------+------------+------+---------------------+---------------------+---------+-------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------------------+------------+------+---------------------+---------------------+---------+-------+------+----------+-----------------------+ | 1 | SIMPLE | book_order | NULL | ref | idx_order_stateDate | idx_order_stateDate | 5 | const | 1 | 100 | Using index condition | +----+-------------+---------------------+------------+------+---------------------+---------------------+---------+-------+------+----------+-----------------------+

和之前的sql比起來(lái),type從index 升級(jí)為 ref(非唯一性索引掃描)。索引的長(zhǎng)度從68變成了5,說(shuō)明只用了一個(gè)索引。ref也是一個(gè)常量。Extra 為Using index condition 表示自動(dòng)根據(jù)臨界值,選擇索引掃描還是全表掃描。總的來(lái)說(shuō)性能遠(yuǎn)勝于之前的sql。

小結(jié)

建索引:

  • 主鍵,唯一索引
  • 經(jīng)常用作查詢條件的字段需要?jiǎng)?chuàng)建索引
  • 經(jīng)常需要排序、分組和統(tǒng)計(jì)的字段需要建立索引
  • 查詢中與其他表關(guān)聯(lián)的字段,外鍵關(guān)系建立索引

不要建索引:

  • 百萬(wàn)級(jí)以下的數(shù)據(jù)不需要?jiǎng)?chuàng)建索引
  • 經(jīng)常增刪改的表不需要?jiǎng)?chuàng)建索引
  • 數(shù)據(jù)重復(fù)且分布平均的字段不需要?jiǎng)?chuàng)建索引
  • 頻發(fā)更新的字段不適合創(chuàng)建索引
  • where條件里用不到的字段不需要?jiǎng)?chuàng)建索引

talk is esay , show me the code

轉(zhuǎn)載于:https://www.cnblogs.com/yizhiamumu/p/9226142.html

總結(jié)

以上是生活随笔為你收集整理的知识点:Mysql 数据库索引优化实战(4)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。