最近在學習深入mysql,記錄一下學習歷程和一些問題,下面的幾種情況是我從網上搜到的,但是在實際測試中卻和網上的結果有出入,希望得到大佬的指點
首先建立表
drop table if exists index_test01;
create table `index_test01`(`
id`int(11) not null auto_increment,/*auto_increment表示自增*/
`a` int(11) ,
`b` int(11) ,
`c` int(11) ,
`d` int(11) ,
primary key (`id
`),/*主鍵*/
key `idx_a`
(`a`
),/*為a欄位建立索引*/
key `idx_b_c`
(`b`
,`c`
)/*為b,c欄位建立聯合索引*/);
drop procedure if exists insert_index_test01; /*如果儲存過程insert_index_test01存在就刪除它*/
delimiter $$ /*改變結束符 mysql的預設結束符為";"*/
create procedure insert_index_test01(
) /*建立儲存過程insert_index_test01*/
begin
declare i int;/*宣告變數i*/
set i=1;/*設定i的初始值為1*/
while
(i<100000)do /*迴圈10萬次*/
insert into index_test01(a,b,c,d) values(i,i,i,i)
; /*自定義sql 這裡是為index_test01新增10萬條資料*/
set i=i+1;
end while
;end $$
delimiter ;/*還原結束符*/
call insert_index_test01(
); /* 執行儲存過程insert_t9_1 */
想要看到明顯的差距的話需要加表的資料
反覆執行
insert into index_test01(a,b,c,d)
select a,b,c,d from index_test01;
現在對比一下不同sql的查詢速度
這個是不走索引的sql
select * from index_test01 where c=9000
查詢結果:
耗時0.45s
這個是走索引的sql
select * from index_test01 where a=9000
耗時0.065s
我們再用explain在看一下
可以看到rows欄位只有16行,代表只掃瞄了一行
可以看到rows欄位只有1596288行,進行了乙個全表掃瞄
直接上sql
select max(a) from index_test01
select max(d) from index_test01
第一條耗時0.033s
第二條耗時0.47s
差距還是非常明顯的
在看在explain下兩條sql的差距
這是也是進行了乙個全表的掃瞄
當我在進行排序時出現了乙個疑問,我的語句是這樣的
select a from index_test01
where a<5000
order by a
查詢耗時4.248s
這裡可以看到只掃瞄了17萬行,是走了索引的
第二條sql
select d from index_test01
where d<5000
order by d
耗時4.625s
掃瞄了150萬行,進行了乙個全表的掃瞄,但是時間卻和第一條差不多,不知道是什麼原因,希望有大佬解惑。
什麼是避免回表呢?以下是個人理解,如果有不對的地方歡迎指正
我們索引所儲存的只是有索引的那個欄位和他的行id,當我們使用索引查出來之後是獲取她的行id,在通過行id去進行掃瞄獲得完整的資料。
select a,d from index_test01 where a<5000
因為我們只有a欄位有索引
所以這裡我們需要分為兩步
1.通過a欄位索引找到行id
2.通過行id再去掃瞄一次磁碟獲取d欄位的資料再返回
select b,c from index_test01 where b<5000
這裡我們是有b、c欄位的聯合索引
索引我們只要通過索引就可以直接獲取到b、c兩個欄位的值 直接返回出去
減少了一次磁碟的掃瞄,所以會快一些。
但是我在實際的測試中發現兩條sql的執行時間都是7秒左右,並沒有太大差別,甚至會出現 聯合索引比單字段索引更慢的情況,希望能有大佬解惑。
建立表index_test02,表結構與index_test01一致
drop table if exists index_test02;
create table index_test02 like index_test01; /* 建立表index_test02,表結構與index_test01一致 */
insert into index_test02
select * from index_test01 limit 2000; /*新增表資料*/
走索引的關聯查詢
select a.a,b.a from index_test01 a
inner join index_test02 b on a.a=b.a
耗時2.402s
不走索引的關聯查詢
select a.d,b.d from index_test01 a
inner join index_test02 b on a.d=b.d
耗時152.070s
相差了一百多秒
到此就結束了,我們做乙個總結
一共有5種情況
資料檢索時在條件字段新增索引
聚合函式對聚合字段新增索引
對排序字段新增索引
為了防止回表新增索引
關聯查詢在關聯字段新增索引
其中3、4這兩種情況我的測試並不符合網上所述,具體原因等我日後更加深入學習後或者有大佬指出問題後再做解答吧
什麼時候需要建索引,什麼時候不需要?
什麼時候要索引?1 表的主鍵 外來鍵必須有索引 2 資料量超過300必須有索引 3 經常與其他表進行連線的表,在連線欄位上建立索引 4 經常出現在where子句的字段,特別是大表字段,必須建索引 5 索引應建立在小字段上,對於大文字字段甚至超長字段,不要建索引 什麼時候不需要索引?1 建立組合索引,...
什麼時候才應該使用HBase?
張貴賓guibin.beijing gmail.com 在使用hbase一定要明白hbase的適用場合,因為hbase並非適用於每種情況。如果有幾億或者幾十億條記錄要存入hbase,那麼hbase就是乙個正確的選擇 否則如果你僅有幾百萬條甚至更少的資料,那麼hbase當然不是正確的選擇,這種情況下應...
什麼時候才應該使用HBase?
在使用hbase一定要明白hbase的適用場合,因為hbase並非適用於每種情況。如果有幾億或者幾十億條記錄要存入hbase,那麼hbase就是乙個正確的選擇 否則如果你僅有幾百萬條甚至更少的資料,那麼hbase當然不是正確的選擇,這種情況下應當選擇傳統的關係型資料庫,因為如果這麼少的資料存入hba...