亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Mysql查詢優(yōu)化的一些實用方法總結(jié)

 更新時間:2022年04月25日 16:07:31   作者:and脫發(fā)周大俠  
對于MySQL查詢語句來說,效率是最重要的,下面這篇文章主要給大家介紹了關(guān)于Mysql查詢優(yōu)化的一些實用方法,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下

指標(biāo):執(zhí)行時間 檢查的行數(shù) 返回的行數(shù)

1. count的優(yōu)化

比如:計算id大于5的城市 a. select count(*) from world.city where id > 5; b. select (select count(*) from world.city) – count(*) from world.city where id <= 5; a語句當(dāng)行數(shù)超過11行的時候需要掃描的行數(shù)比b語句要多, b語句掃描了6行,此種情況下,b語句比a語句更有效率。當(dāng)沒有where語句的時候直接select count(*) from world.city這樣會更快,因為mysql總是知道表的行數(shù)。

案例:

# 建庫
CREATE DATABASE IF NOT EXISTS db3 DEFAULT CHARSET=utf8;
USE db3;
# 建表
CREATE TABLE IF NOT EXISTS cnt(id INT , NAME VARCHAR(10),age INT ,tel VARCHAR(10));
# 創(chuàng)建存儲過程 procedrue  
DELIMITER $
CREATE PROCEDURE cnt()
BEGIN
#定義變量 declare
DECLARE i INT DEFAULT 0;
WHILE(i<100000) DO
    BEGIN
        SELECT i;
        SET i=i+1;
        INSERT INTO cnt(id,NAME)VALUES(i,'zs');
    END;
END WHILE;
END $
DELIMITER ;
#調(diào)用存儲過程
CALL cnt();

    
SELECT COUNT(*)FROM cnt;
#執(zhí)行耗時   : 0 sec 傳送時間   : 0.051 sec 總耗時      : 0.051 sec
#數(shù)據(jù)庫知道表內(nèi)有多少條數(shù)據(jù)    

SELECT COUNT(*) FROM cnt WHERE id > 5;  
# 執(zhí)行耗時   : 0.130 sec 傳送時間   : 0 sec 總耗時      : 0.130 sec
# 使用where 掃描了全表 id > 5的所有數(shù)據(jù) 總查詢99995條

SELECT (SELECT COUNT(*) FROM cnt) - COUNT(*) FROM cnt WHERE id <=5 ;
# 執(zhí)行耗時   : 0.080 sec 傳送時間   : 0 sec  總耗時      : 0.081 sec
# 使用where 掃描全表 id <= 5 的五條數(shù)據(jù)  加上 (SELECT COUNT(*) FROM cnt) 一條數(shù)據(jù) 總查詢 6 條

2. 避免使用不兼容的數(shù)據(jù)類型。

例如float和int、char和varchar、binary和varbinary是不兼容的。數(shù)據(jù)類型的不兼容可能使優(yōu)化器無法執(zhí)行一些本來可以進(jìn)行的優(yōu)化操作。 在程序中,保證在實現(xiàn)功能的基礎(chǔ)上,盡量減少對數(shù)據(jù)庫的訪問次數(shù);通過搜索參數(shù),盡量減少對表的訪問行數(shù),最小化結(jié)果集,從而減輕網(wǎng)絡(luò)負(fù)擔(dān);

能夠分開的操作盡量分開處理,提高每次的響應(yīng)速度;

在數(shù)據(jù)窗口使用SQL時,盡量把使用的索引放在選擇的首列;算法的結(jié)構(gòu)盡量簡單;在查詢時,不要過多地使用通配符如 SELECT * FROM T1語句,要用到幾列就選擇幾列如:SELECT COL1,COL2 FROM T1;

在可能的情況下盡量限制盡量結(jié)果集行數(shù)如:SELECT TOP 300 COL1,COL2,COL3 FROM T1,因為某些情況下用戶是不需要那么多的數(shù)據(jù)的。不要在應(yīng)用中使用數(shù)據(jù)庫游標(biāo),游標(biāo)是非常有用的工具,但比使用常規(guī)的、面向集的SQL語句需要更大的開銷;按照特定順序提取數(shù)據(jù)的查找。

案例:

# 創(chuàng)建一個表測試了一下 int 類型數(shù)據(jù)插入float類型的數(shù)據(jù)  結(jié)果:插入數(shù)度變慢 會四舍五入
CREATE TABLE sss(id INT);
INSERT INTO sss VALUES(12.4);
INSERT INTO sss VALUES(12.5);

3. 索引字段上進(jìn)行運算會使索引失效。

盡量避免在WHERE子句中對字段進(jìn)行函數(shù)或表達(dá)式操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。

如:SELECT * FROM T1 WHERE F1/2=100 應(yīng)改為: SELECT * FROM T1 WHERE F1=100*2

案例:

#創(chuàng)建索引
CREATE INDEX index_id ON cnt(id);

SELECT * FROM cnt WHERE id > 50000;
#行耗時   : 0.009 sec  傳送時間   : 0 sec  總耗時      : 0.010 sec
SELECT * FROM cnt WHERE id*2 > 100000;
#執(zhí)行耗時   : 0.031 sec 傳送時間   : 0 sec  總耗時      : 0.032 sec
# 使用了索引進(jìn)行運算  使得索引失效 效率變慢了

4. 避免使用!=或<>、IS NULL或IS NOT NULL、IN ,NOT IN等這樣的操作符.

因為這會使系統(tǒng)無法使用索引,而只能直接搜索表中的數(shù)據(jù)。例如: SELECT id FROM employee WHERE id != “B%” 優(yōu)化器將無法通過索引來確定將要命中的行數(shù),因此需要搜索該表的所有行。在in語句中能用exists語句代替的就用exists.

5. 盡量使用數(shù)字型字段.

一部分開發(fā)人員和數(shù)據(jù)庫管理人員喜歡把包含數(shù)值信息的字段 設(shè)計為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。這是因為引擎在處理查詢和連接回逐個比較字符串中每一個字符,而對于數(shù)字型而言只需要比較一次就夠了。

6. 合理使用EXISTS,NOT EXISTS子句。如下所示:

SELECT SUM(T1.C1) FROM T1 WHERE (SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0) 2.SELECT SUM(T1.C1) FROM T1WHERE EXISTS(SELECT * FROM T2 WHERE T2.C2=T1.C2) 兩者產(chǎn)生相同的結(jié)果,但是后者的效率顯然要高于前者。

因為后者不會產(chǎn)生大量鎖定的表掃描或是索引掃描。如果你想校驗表里是否存在某條紀(jì)錄,不要用count(*)那樣效率很低,而且浪費服務(wù)器資源??梢杂肊XISTS代替。如:IF (SELECT COUNT(*) FROM table_name WHERE column_name = ‘xxx’)

可以寫成:IF EXISTS (SELECT * FROM table_name WHERE column_name = ‘xxx’)

7. 能夠用BETWEEN的就不要用IN

8. 能夠用DISTINCT的就不用GROUP BY

9. 盡量不要用SELECT INTO語句。

SELECT INTO 語句會導(dǎo)致表鎖定,阻止其他用戶訪問該表。

10. 必要時強制查詢優(yōu)化器使用某個索引

SELECT * FROM T1 WHERE nextprocess = 1 AND processid IN (8,32,45)

改成: SELECT * FROM T1 (INDEX = IX_ProcessID) WHERE nextprocess = 1 AND processid IN (8,32,45)

則查詢優(yōu)化器將會強行利用索引IX_ProcessID 執(zhí)行查詢。

案例:

# 10.必要時強制查詢優(yōu)化器使用索引
#建表
create table if not exists T1(processid int, nextprocess int);
#建索引
create index index_processID on T1(processid);
# 10.1:不使用索引
select * from T1 where nextprocess = 1 and processid in (8,32,45);
# 10.2: 強制使用索引
select * from T1 froce index(index_processID)
 where nextprocess = 1 and process = 1 and processid in (8,32,45);

11. 消除對大型表行數(shù)據(jù)的順序存取

盡管在所有的檢查列上都有索引,但某些形式的WHERE子句強迫優(yōu)化器使用順序存取。如: SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008 解決辦法可以使用并集來避免順序存?。?SELECT * FROM orders WHERE customer_num=104 AND order_num>1001 UNION SELECT * FROM orders WHERE order_num=1008 這樣就能利用索引路徑處理查詢?!緅acking 數(shù)據(jù)結(jié)果集很多,但查詢條件限定后結(jié)果集不大的情況下,后面的語句快】

案例:

# 11.消除對大型表 行數(shù)據(jù)的順序存取
#建表
create table if not exists orders(customer_num int, order_num int);
# 消除順序索引
#11.1 沒有使用索引
select * from orders where (customer_num=104 and order_num > 100) or order_num=1005;
#11.2 使用索引  將or 拆開 避免使用or
select * from orders where custoner_num = 104 and order_num > 100
union  # union 默認(rèn)去重,排序   union all 不去重,不會排序 
select * from orders where order_num=1005;

12. 盡量避免在索引過的字符數(shù)據(jù)中,使用非打頭字母搜索。這也使得引擎無法利用索引。

見如下例子: SELECT * FROM T1 WHERE NAME LIKE ‘%L%’ SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=’L’ SELECT * FROM T1 WHERE NAME LIKE ‘L%’ 即使NAME字段建有索引,前兩個查詢依然無法利用索引完成加快操作,引擎不得不對全表所有數(shù)據(jù)逐條操作來完成任務(wù)。而第三個查詢能夠使用索引來加快操作,不要習(xí)慣性的使用 ‘%L%’這種方式(會導(dǎo)致全表掃描),如果可以使用`L%’相對來說更好;

 案例:

# 12. 模糊查詢where like ,字母打頭'1%' 會使用索引 即%在右
create table if not exists T2(name varchar(20));
create index  index_name on T2(name);
# 12.1 不會使用索引
select * from T2 where name like '%L%';
select * from T2 where name like '%L';
    #substring 進(jìn)行字符串截取 參數(shù):字符串,起始位置,結(jié)束位置
select * from T2 where substring(name,2,1)='L'; 
# 12.2 使用到索引
select * from T2 where name like 'L%';

13. 雖然UPDATE、DELETE語句的寫法基本固定,但是還是對UPDATE語句給點建議:

a) 盡量不要修改主鍵字段。 b) 當(dāng)修改VARCHAR型字段時,盡量使用相同長度內(nèi)容的值代替。 c) 盡量最小化對于含有UPDATE觸發(fā)器的表的UPDATE操作。 d) 避免UPDATE將要復(fù)制到其他數(shù)據(jù)庫的列。 e) 避免UPDATE建有很多索引的列。 f) 避免UPDATE在WHERE子句條件中的列。

14. 能用UNION ALL就不要用UNION

UNION ALL不執(zhí)行SELECT DISTINCT函數(shù),這樣就會減少很多不必要的資源 在跨多個不同的數(shù)據(jù)庫時使用UNION是一個有趣的優(yōu)化方法,UNION從兩個互不關(guān)聯(lián)的表中返回數(shù)據(jù),這就意味著不會出現(xiàn)重復(fù)的行,同時也必須對數(shù)據(jù)進(jìn)行排序,我們知道排序是非常耗費資源的,特別是對大表的排序。 UNION ALL可以大大加快速度,如果你已經(jīng)知道你的數(shù)據(jù)不會包括重復(fù)行,或者你不在乎是否會出現(xiàn)重復(fù)的行,在這兩種情況下使用UNION ALL更適合。此外,還可以在應(yīng)用程序邏輯中采用某些方法避免出現(xiàn)重復(fù)的行,這樣UNION ALL和UNION返回的結(jié)果都是一樣的,但UNION ALL不會進(jìn)行排序。

15. 字段數(shù)據(jù)類型優(yōu)化:

a. 避免使用NULL類型:NULL對于大多數(shù)數(shù)據(jù)庫都需要特殊處理,MySQL也不例外,它需要更多的代碼,更多的檢查和特殊的索引邏輯,有些開發(fā)人員完全沒有意識到,創(chuàng)建表時NULL是默認(rèn)值,但大多數(shù)時候應(yīng)該使用NOT NULL,或者使用一個特殊的值,如0,-1作為默認(rèn)值。 b. 盡可能使用更小的字段,MySQL從磁盤讀取數(shù)據(jù)后是存儲到內(nèi)存中的,然后使用cpu周期和磁盤I/O讀取它,這意味著越小的數(shù)據(jù)類型占用的空間越小,從磁盤讀或打包到內(nèi)存的效率都更好,但也不要太過執(zhí)著減小數(shù)據(jù)類型,要是以后應(yīng)用程序發(fā)生什么變化就沒有空間了。修改表將需要重構(gòu),間接地可能引起代碼的改變,這是很頭疼的問題,因此需要找到一個平衡點。 c. 優(yōu)先使用定長型

16. 關(guān)于大數(shù)據(jù)量limit分布的優(yōu)化見下面鏈接(當(dāng)偏移量特別大時,limit效率會非常低):

http://ariyue.iteye.com/blog/553541 附上一個提高limit效率的簡單技巧,在覆蓋索引(覆蓋索引用通俗的話講就是在select的時候只用去讀取索引而取得數(shù)據(jù),無需進(jìn)行二次select相關(guān)表)上進(jìn)行偏移,而不是對全行數(shù)據(jù)進(jìn)行偏移。可以將從覆蓋索引上提取出來的數(shù)據(jù)和全行數(shù)據(jù)進(jìn)行聯(lián)接,然后取得需要的列,會更有效率,看看下面的查詢: mysql> select film_id, description from sakila.film order by title limit 50, 5; 如果表非常大,這個查詢最好寫成下面的樣子: mysql> select film.film_id, film.description from sakila.film inner join(select film_id from sakila.film order by title liimit 50,5) as film usinig(film_id);

17. 程序中如果一次性對同一個表插入多條數(shù)據(jù),比如以下語句:

insert into person(name,age) values(‘xboy’, 14); insert into person(name,age) values(‘xgirl’, 15); insert into person(name,age) values(‘nia’, 19); 把它拼成一條語句執(zhí)行效率會更高. insert into person(name,age) values(‘xboy’, 14), (‘xgirl’, 15),(‘nia’, 19);

18. 不要在選擇的欄位上放置索引,這是無意義的。

應(yīng)該在條件選擇的語句上合理的放置索引,比如where,order by。

SELECT id,title,content,cat_id FROM article WHERE cat_id = 1;

19. ORDER BY語句的MySQL優(yōu)化:

a. ORDER BY + LIMIT組合的索引優(yōu)化。

如果一個SQL語句形如:

SELECT [column1],[column2],…. FROM [TABLE] ORDER BY [sort] LIMIT [offset],[LIMIT];

這個SQL語句優(yōu)化比較簡單,在[sort]這個欄位上建立索引即可。

b. WHERE + ORDER BY + LIMIT組合的索引優(yōu)化,形如:

SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] = [VALUE] ORDER BY [sort] LIMIT [offset],[LIMIT];

這個語句,如果你仍然采用第一個例子中建立索引的方法,雖然可以用到索引,但是效率不高。更高效的方法是建立一個聯(lián)合索引(columnX,sort)

c. WHERE + IN + ORDER BY + LIMIT組合的索引優(yōu)化,形如:

SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] IN ([value1],[value2],…) ORDER BY [sort] LIMIT [offset],[LIMIT];

這個語句如果你采用第二個例子中建立索引的方法,會得不到預(yù)期的效果(僅在[sort]上是using index,WHERE那里是using where;using filesort),理由是這里對應(yīng)columnX的值對應(yīng)多個。 目前哥還木有找到比較優(yōu)秀的辦法,等待高手指教。

d.WHERE+ORDER BY多個欄位+LIMIT,比如:

SELECT * FROM [table] WHERE uid=1 ORDER x,y LIMIT 0,10;

對于這個語句,大家可能是加一個這樣的索引:(x,y,uid)。但實際上更好的效果是(uid,x,y)。這是由MySQL處理排序的機制造成的。

總結(jié)

到此這篇關(guān)于Mysql查詢優(yōu)化的一些實用方法的文章就介紹到這了,更多相關(guān)Mysql查詢優(yōu)化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 強制修改mysql的root密碼的六種方法分享(mysql忘記密碼)

    強制修改mysql的root密碼的六種方法分享(mysql忘記密碼)

    下面我們提供了6種不同的修改mysql root用戶的密碼,與增加mysql用戶的方法
    2011-11-11
  • mysql 5.7.24 安裝配置方法圖文教程

    mysql 5.7.24 安裝配置方法圖文教程

    這篇文章主要為大家詳細(xì)介紹了mysql 5.7.24 安裝配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • MySQL 權(quán)限控制詳解

    MySQL 權(quán)限控制詳解

    這篇文章主要介紹了MySQL 權(quán)限控制詳解的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下
    2021-03-03
  • mysql實現(xiàn)設(shè)置定時任務(wù)的方法分析

    mysql實現(xiàn)設(shè)置定時任務(wù)的方法分析

    這篇文章主要介紹了mysql實現(xiàn)設(shè)置定時任務(wù)的方法,結(jié)合實例形式分析了mysql定時任務(wù)相關(guān)的事件計劃設(shè)置與存儲過程使用等操作技巧,需要的朋友可以參考下
    2019-10-10
  • 忘記MySQL的root密碼該怎么辦

    忘記MySQL的root密碼該怎么辦

    忘記密碼總是一件令人頭疼的事情,當(dāng)我們忘記了MySQL的root密碼該怎么辦?本文給出解決方法,感興趣的小伙伴們可以參考一下
    2016-05-05
  • 高性能MySQL讀書筆記 找出誰持有鎖

    高性能MySQL讀書筆記 找出誰持有鎖

    周末重讀了一遍《高性能MySQL》,發(fā)現(xiàn)有些知識點看過便忘了,沒有實際動手操作一遍就是記不牢,所以今天動手操作了一下“找出誰持有鎖”,并把實驗步驟記錄下來,有興趣的網(wǎng)友可以參照一二。
    2011-01-01
  • MySql安裝啟動兩種方法教程詳解

    MySql安裝啟動兩種方法教程詳解

    本文通過兩種方法給大家介紹mysql安裝啟動的方法,非常不錯,具有參考價值,有需要的朋友一起學(xué)習(xí)吧
    2016-05-05
  • MySql中刪除數(shù)據(jù)表的方法詳解

    MySql中刪除數(shù)據(jù)表的方法詳解

    這篇文章主要介紹了MySql中刪除數(shù)據(jù)表的方法的相關(guān)資料,作者講解的十分細(xì)致全面,這里推薦給大家,需要的朋友可以參考下
    2022-08-08
  • MySQL數(shù)據(jù)庫主機127.0.0.1與localhost區(qū)別

    MySQL數(shù)據(jù)庫主機127.0.0.1與localhost區(qū)別

    這篇文章主要介紹了MySQL主機127.0.0.1與localhost區(qū)別總結(jié),需要的朋友可以參考下
    2018-06-06
  • 安裝的mysql中沒有my.ini文件的解決方法

    安裝的mysql中沒有my.ini文件的解決方法

    本文主要介紹了安裝的mysql中沒有my.ini文件的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03

最新評論