Re: [SQL ] mysql date column index 問題

看板Database作者 (ing)時間10年前 (2013/09/17 22:39), 編輯推噓1(107)
留言8則, 2人參與, 最新討論串2/2 (看更多)
※ 引述《kaiyuegg (蛋頭)》之銘言: : 大家好~! : MYSQL VER.5.0.51b-community-nt-log : 我最近在研究系統效能部分(有關於 mysql date index 沒反應)... : 遇到了一些問題! : 我一般在處理日期部分 都是直接這樣下的 : select * from `salary` where DATE < '2013-09-15' : 但有時候筆數多的時候就算DATE 設 index : mysql explain 的type 也是 all (索引沒發揮作用) : 這樣效能很差 所以在找方法讓它變快。 : 如果設 : select * from salary where DATE between '2013-05-10' and '2014-09-29' : explain 出來 type 才會變成 range : (索引有發生作用 但是好像要設到資料裡面的上限跟下限裡面才有作用) : 如果資料裡面包含 0000-00-00 想要抓不包含0000-00-00的資料想要這樣下 : select * from salary where DATE between '1970-01-01 and '2050-12-31' : 這時候explain 出來 就變成all 了(索引就沒發生作用了) : 下 != or <> 0000-00-00 也會變成all : 結論 : 1.想請問大家 mysql 在日期欄位上面 index 的正確用法? : 2.如上面所述 我想要抓不是0000-00-00 的資料 用什麼方法可以讓index 產生效用? : 可能說的不是很清楚...但就是date 在 mysql 的索引好像不是那麼友善? : 請大大指點迷津 或是提示一下 我不清楚的部分 tks 首先你要知道 INDEX 是另外存的 也佔空間 也吃 FILE IO 也就是說 透過 INDEX 其實不一定比較快 例如你有一個 TABLE 總共佔了 10000 個 block 然後建了一個 index , 這個 index 本身佔了 2000 個 block 假設你今天要找的資料 在整個 table 的 10000 個 blocks 裡, 散布在其中的 9000 個 blocks 裡面。 這時候 你透過 index 找資料的 IO 成本就會是 2000 + 9000 = 11000 而 Full Table Scan 的 IO 成本只有 10000 像這樣的時候, DBMS 就會選擇直接做 Table Scan 因為成本比較低。 那 DBMS 怎麼知道哪條路成本比較低呢 就來自它本身對這些 表格/索引 的統計值 以 Oracle 舉例 跟這樣行為有關的參數就包括有 1. 最佳化器嘗試組出最佳路徑的嘗試次數上限 2. 最佳化器判斷 走 index 的成本 大於 Full Table Scan 成本的多少比例以上 就走 Full Scan 3. 最佳化器優化的方向(最小IO , 最快回應等 回到你提的問題 從你下的參數中我們可以注意到幾件事 1. 在你指定的範圍內資料量較小的時候 DBMS 會覺得該走 index 2. 在你指定的範圍內資料量較大的時候 DBMS 選擇走 FULL SCAN 3. 你下了 select * 這代表所有不在INDEX上的欄位,DBMS都必須要翻 DATA BLOCKS出來才能拿到資料 但是在你的資料中 0000-00-00 的資料量到底有多少? 如果只有很小一點點 (或是 DBMS 覺得它只佔一點點 那麼使用 FULL SCAN 是很正常的。 反正你都得翻這些資料出來,何必脫褲子放屁去 index blocks 再繞一圈呢? 但是如果 這樣的資料是佔多數的 那或許是你的表格/索引的統計值出問題了。導致 DBMS 覺得這樣比較快 * 有另一個狀況 就是 DBMS 在處理 function(col) 這些操作的時候 因為存在 index 裡的資料是 col 而非 function(col) 所以 DBMS 會覺得這個 index 是與需求不符的 會放棄 ** 然後 資料量大的話 會慢是正常的啊 有吃 IO 吃CPU 就有開銷就是要花工夫啊 你只能避免它繞冤枉路 該走的路還是免不了的 ---- 會看執行計畫之後的下一步就是算執行成本 加油啊~ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 122.118.6.179 jeamie:轉錄至某隱形看板 09/17 22:51 ※ 編輯: iFEELing 來自: 122.118.6.179 (09/17 23:02)

09/19 13:08, , 1F
感謝回應~我也有了觀念的釐清!
09/19 13:08, 1F

09/19 13:08, , 2F
先講0000-00-00是大約佔七成...當我把它改成1000-01-01
09/19 13:08, 2F

09/19 13:09, , 3F
索引就發揮作用了~!
09/19 13:09, 3F

09/19 13:09, , 4F
但我有一個不解想請問i大~! 索引在我認知裡面以為是一張
09/19 13:09, 4F

09/19 13:10, , 5F
排序不同但一樣大小的table 請問一下 10000 block 索引
09/19 13:10, 5F

09/19 13:10, , 6F
不是 10000 而是大約 2000 block 我這部分不太清楚
09/19 13:10, 6F

09/19 13:11, , 7F
可以請i大說明一下嗎?~謝謝您
09/19 13:11, 7F

09/19 15:10, , 8F
完全不是這樣的喔 索引是TREE 不是表格 只記特定欄位
09/19 15:10, 8F
文章代碼(AID): #1IE6cDVe (Database)
文章代碼(AID): #1IE6cDVe (Database)