1. 計數器表
案例:網站訪問數記錄
正常一張表一個字段就可以解決這個問題。
create table tcount (cnt int) ;
通過左邊語句更新:
update tcount set cnt = cnt+1 ;
當大型網站併發量很大的時候,這個更新是低效的。因爲update操作需要獲取寫鎖。
優化如下:
創建一張表:
create table tcount (cnt int,id int primary key) ;
先寫入100條數據, id 從1-100. cnt 都爲零。
然後隨機更新:
update tcount set cnt = cnt+1 where id = ROUND(rand()*100) ;
最後統計:
select count(cnt) from tcount;
這樣做,很好的避免了每次更新都需要拿行鎖的問題(效率自然就高了)。
2. 僞哈希索引
create table turl(url varchar(100), url_crc varchar(32));
爲了測試插入數據:
insert into turl(url,url_crc) values('https://www.cnblogs.com/jssj/',CRC32('https://www.cnblogs.com/jssj/')); insert into turl(url,url_crc) values('https://spring.io/',CRC32('https://spring.io/')); insert into turl(url,url_crc) values('http://www.sikiedu.com/',CRC32('http://www.sikiedu.com/')); insert into turl(url,url_crc) values('http://seventhicecastle.com/',CRC32('http://seventhicecastle.com/'));
索引改成建立在url_crc字段上:
查詢SQL:
select * from turl where url_crc = CRC32('https://www.cnblogs.com/jssj/') and url = 'https://www.cnblogs.com/jssj/';
因爲CRC32 屬於摘要信息,存在url不同卻crc32後的摘要相同的情況,所以還需要加上url的條件。因爲索引在url_crc上,執行效率非常高的。
摘要信息詳情參考:https://www.cnblogs.com/jssj/p/12001431.html
3. 前綴索引
創建前綴索引:
alter table turl add key(url(7));
列值比較長的時候,因爲整列作爲索引太浪費索引空間。
4. 重新整理數據空間。
optimize table cop_ttransferflow;
查詢表的索引信息
show index from XXXX; -- XXXX 表名
5. like SQL優化,準備一張百萬數據量的表(ic_website)
select t.* from ic_website t where t.url like '%72511%' ;
第一次執行花費9S.
select * from ic_website t1 INNER JOIN (select t.id,t.url from ic_website t where t.url like '%72511%' ) t2 on t1.id = t2.id ;
改寫之後:第一次執行時間花費0.9S
6. 創建索引技巧
alter table t add index index2(sex,username); -- 創建這樣一個索引,大家都會覺得使用username的時候無法走索引,但是,其實可以有一個小技巧
可以使用一個小技巧。
運行效率提高20倍。
範圍查詢到導致,後面字段都無法使用索引,範圍查詢字段需要放索引最後面,例如日期。
7. order by 字段如果不在索引裏面也會很慢,可以加索引看結果。
8. limit分頁優化
select * from t where t.sex = '0' order by t.username LIMIT 10 ;
select * from t where t.sex = '0' order by t.username LIMIT 1000000, 10 ;
分頁取越後面會越慢。
limit優化前:
select * from t where t.sex = '0' order by t.id LIMIT 1000000, 10 ;
優化後:
select * from t where t.sex = '0' and t.id > 5600677 order by t.id LIMIT 10 ;
9. 分解關聯查詢
優化前:
SELECT * FROM tuser t, trole t1, tcompany t2 WHERE t.role_id = t1.role_id AND t1.company_id = t2.company_id and t.user_age = 33;
優化後:
SELECT * FROM tuser t where t.user_age = 33; SELECT * FROM trole t where t.role_id = 9; select * from tcompany t where t.company_id in (1,2);
優化的好處有:
1. 讓MYSQL緩存可以更好的利用。
2. 減少鎖表的情況。
3. 查詢簡化,減少笛卡爾積。