作者iFEELing (ing)
看板Database
标题Re: [SQL ] mysql date column index 问题
时间Tue Sep 17 22:39:06 2013
※ 引述《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)
1F:推 kaiyuegg:感谢回应~我也有了观念的厘清! 09/19 13:08
2F:→ kaiyuegg:先讲0000-00-00是大约占七成...当我把它改成1000-01-01 09/19 13:08
3F:→ kaiyuegg:索引就发挥作用了~! 09/19 13:09
4F:→ kaiyuegg:但我有一个不解想请问i大~! 索引在我认知里面以为是一张 09/19 13:09
5F:→ kaiyuegg:排序不同但一样大小的table 请问一下 10000 block 索引 09/19 13:10
6F:→ kaiyuegg:不是 10000 而是大约 2000 block 我这部分不太清楚 09/19 13:10
7F:→ kaiyuegg:可以请i大说明一下吗?~谢谢您 09/19 13:11
8F:→ iFEELing:完全不是这样的喔 索引是TREE 不是表格 只记特定栏位 09/19 15:10