sql優化大全

?1. 優化SQL步驟

1. 通過 show status和應用特點了解各種 SQL的執行頻率

? ? ? ?通過 SHOW STATUS 可以提供服務器狀態信息,也可以使用 mysqladmin extende d-status 命令獲得。 SHOW STATUS 可以根據需要顯示 session 級別的統計結果和 global級別的統計結果。

? ? ? ?如顯示當前session:?SHOW STATUS like "Com_%"; 全局級別:show global status;
? ? ? ?以下幾個參數對 Myisam 和 Innodb 存儲引擎都計數:

1. Com_select 執行 select 操作的次數,一次查詢只累加 1 ;

2. Com_insert 執行 insert 操作的次數,對于批量插入的 insert 操作,只累加一次 ;

3. Com_update 執行 update 操作的次數;

4. Com_delete 執行 delete 操作的次數;

? ? ? ? 以下幾個參數是針對 Innodb 存儲引擎計數的,累加的算法也略有不同:

1. Innodb_rows_read select 查詢返回的行數;

2. Innodb_rows_inserted 執行 Insert 操作插入的行數;

3. Innodb_rows_updated 執行 update 操作更新的行數;

4. Innodb_rows_deleted 執行 delete 操作刪除的行數;

? ? ? ?通過以上幾個參數,可以很容易的了解當前數據庫的應用是以插入更新為主還 是以查詢操作為主,以及各種類型的 SQL大致的執行比例是多少。對于更新操作的計 數,是對執行次數的計數,不論提交還是回滾都會累加。
? ? ? 對于事務型的應用,通過 Com_commit 和 Com_rollback 可以了解事務提交和回 滾的情況,對于回滾操作非常頻繁的數據庫,可能意味著應用編寫存在問題。此外,以下幾個參數便于我們了解數據庫的基本情況:

1. Connections 試圖連接 MySQL 服務器的次數
2. Uptime 服務器工作時間
3. Slow_queries 慢查詢的次數


2. 定位執行效率較低的SQL語句

? ? ?可以通過以下兩種方式定位執行效率較低的 SQL 語句:
? ? ?1. 可以通過慢查詢日志定位那些執行效率較低的 sql 語句,用 --log-slow-queries[=file_name] 選項啟動時, mysqld 寫一個包含所有執行時間超過long_query_time 秒的 SQL 語句的日志文件。可以鏈接到管理維護中的相關章節。
? ? ?2. 使用 show processlist查看當前mysql的線程, 命令慢查詢日志在查詢結束以后才紀錄,所以在應用反映執行效率出現問題的時候查 詢慢查詢日志并不能定位問題,可以使用 show processlist 命令查看當前 MySQL 在進行的線程,包括線程的狀態,是否鎖表等等,可以實時的查看 SQL 執行情況, 同時對一些鎖表操作進行優化。

3. 通過EXPLAIN 分析低效 SQL的執行計劃:

? ? ? ?通過以上步驟查詢到效率低的 SQL 后,我們可以通過 explain 或者 desc 獲取MySQL 如何執行 SELECT 語句的信息,包括 select 語句執行過程表如何連接和連接 的次序。

2. MySQL索引

1. mysql如何使用索引 ? ?

? ? ? ?索引用于快速找出在某個列中有一特定值的行。對相關列使用索引是提高SELECT 操作性能的最佳途徑。
? ? ? ?查詢要使用索引最主要的條件是查詢條件中需要使用索引關鍵字,如果是多列 索引,那么只有查詢條件使用了多列關鍵字最左邊的前綴時(前綴索引),才可以使用索引,否則 將不能使用索引。

? ? ? ?下列情況下, Mysql 不會使用已有的索引:
? ? ? 1、如果 mysql 估計使用索引比全表掃描更慢,則不使用索引。例如:如果 key_part 1均勻分布在 1 和 100 之間,下列查詢中使用索引就不是很好:
? ? ? ? SELECT * FROM table_name where key_part1 > 1 and key_part1 < 90
? ? ? 2、如果使用 heap 表并且 where 條件中不用=索引列,其他 > 、 < 、 >= 、 <= 均不使 用索引(MyISAM和innodb表使用索引)

? ? ? 3、使用or分割的條件,如果or前的條件中的列有索引,后面的列中沒有索引,那么涉及到的索引都不會使用。
? ? ? 4、如果創建復合索引,如果條件中使用的列不是索引列的第一部分;(不是前綴索引)
? ? ? 4、如果 like 是以%開始;

? ? ? 5、對 where 后邊條件為字符串的一定要加引號,字符串如果為數字 mysql 會自動轉 為字符串,但是不使用索引。

2. 查看索引使用情況

? ? ? ? 如果索引正在工作, Handler_read_key 的值將很高,這個值代表了一個行被索引值讀的次數,很低的值表明增加索引得到的性能改善不高,因為索引并不經常使 用。
Handler_read_rnd_next 的值高則意味著查詢運行低效,并且應該建立索引補救。這個值的含義是在數據文件中讀下一行的請求數。如果你正進行大量的表掃描,
該值較高。通常說明表索引不正確或寫入的查詢沒有利用索引。
? ? ? ?語法:
? ? ? ? mysql> show status like 'Handler_read%';

?

3. 具體優化查詢語句

1. 查詢進行優化,應盡量避免全表掃描

? ? 對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引

? ? ? ?.? ? 嘗試下面的技巧以避免優化器錯選了表掃描:

? ? ????使用ANALYZE TABLEtbl_name為掃描的表更新關鍵字分布。

? ? ? ?·???對掃描的表使用FORCEINDEX告知MySQL,相對于使用給定的索引表掃描將非常耗時。

? ? ? ? ? ??SELECT * FROM t1, t2 FORCE INDEX (index_for_column) ??WHERE t1.col_name=t2.col_name

? ? ????用--max-seeks-for-key=1000選項啟動mysqld或使用SET max_seeks_for_key=1000告知優化器假設關鍵字掃描不會超過1,000次關鍵字搜索。

?1). 應盡量避免在 where 子句中對字段進行 null 值判斷

? ? ? ? 否則將導致引擎放棄使用索引而進行全表掃描,如:

? ? ? ??select id from t where num is null

? ? ? ? NULL對于大多數數據庫都需要特殊處理,MySQL也不例外,它需要更多的代碼,更多的檢查和特殊的索引邏輯,有些開發人員完全沒有意識到,創建表時NULL是默認值,但大多數時候應該使用NOT NULL,或者使用一個特殊的值,如0,-1作為默? 認值。

? ? ? ? 不能用null作索引,任何包含null值的列都將不會被包含在索引中。即使索引有多列這樣的情況下,只要這些列中有一列含有null,該列??? 就會從索引中排除。也就是說如果某列存在空值,即使對該列建索引也不會提高性能。 任何在where子句中使用is null或is not null的語句優化器是不允許使用索引的。

? ? ? ? 此例可以在num上設置默認值0,確保表中num列沒有null值,然后這樣查詢:

? ? ? ? ?select id??? from t where num=0

?2). 應盡量避免在 where 子句中使用!=或<>操作符

? ? ? ? ?否則將引擎放棄使用索引而進行全表掃描。
? ? ? ? ?MySQL只有對以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些時候的LIKE。?

? ? ? ? ?可以在LIKE操作中使用索引的情形是指另一個操作數不是以通配符(%或者_)開頭的情形。例如:
? ? ? ? ?SELECT id FROM ?t WHERE col LIKE 'Mich%'; #??這個查詢將使用索引,
? ? ? ? ?SELECT id FROM ?t WHERE col ?LIKE '%ike'; ? #這個查詢不會使用索引。

?3). 應盡量避免在 where 子句中使用 or 來連接條件

? ? ? ? 否則將導致引擎放棄使用索引而進行全表掃描,如:

? ? ? ???使用UNION合并查詢: select id from t where num=10 union all select id from t where num=20

??????????

?????? 在某些情況下,or條件可以避免全表掃描的。

??????? 1 .where 語句里面如果帶有or條件, myisam表能用到索引, innodb不行。

?????????? 2 .必須所有的or條件都必須是獨立索引

?????? mysql or條件可以使用索引而避免全表


?4) .in 和 not in 也要慎用,否則會導致全表掃描,

? ? ? ? 如:

? ? ? ??select id from t where num in(1,2,3)

? ? ? ? 對于連續的數值,能用 between 就不要用 in 了:

? ? ? ??? 5).下面的查詢也將導致全表掃描:

? ? ? ? select id from t where name like '%abc%' 或者

? ? ? ? select id from t where name like '%abc' 或者

? ? ? ? 若要提高效率,可以考慮全文檢索。

? ? ? ? 而select id from t where name like 'abc%' 才用到索引

?

MySql in子句 效率低下優化

?

背景:

?

?更新一張表中的某些記錄值,更新條件來自另一張含有200多萬記錄的表,效率極其低下,耗時高達幾分鐘。

?

update clear_res set candelete=0 where resid in
(select distinct resourceid from att_attentionresult where important=0
);

?

耗時 365s

?

?

?

優化后

?

 update clear_res set candelete=0 where resid in
(select resourceid from (select distinct resourceid from att_attentionresult where important=0) as tmp
);

?

耗時 1.41s

?

?

?

總結:對于where xxx in 子句效率極其低下問題,經過in的子句外包裝一層select xxx from( ... )as tmp 后,極大優化效率。

?

?7). 如果在 where 子句中使用參數,也會導致全表掃描。

? ? ? ?因為SQL只有在運行時才會解析局部變量,但優化程序不能將訪問計劃的選擇推 遲到運行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變量的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描:

? ? ? ?select id from t where num=@num

? ? ? ?可以改為強制查詢使用索引: select id from t with(index(索引名)) where?num=@num

?8). 應盡量避免在 where 子句中對字段進行表達式操作,

? ? ? ?這將導致引擎放棄使用索引而進行全表掃描。如:

? ? ? ?select id from t where num=100*2

9). 應盡量避免在where子句中對字段進行函數操作,

? ? ? ?這將導致引擎放棄使用索引而進行全表掃描。如:

? ? ? select id from t where substring(name,1,3)='abc' ? --name

? ? ? select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’?

? ? ? 生成的id 應改為:

? ? ? select id from t where name like 'abc%'

? ? ? select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'

10).不要在 where 子句中的“=”左邊進行函數、算術運算或其他表達式運算,

? ? ? 否則系統將可能無法正確使用索引。

11).?索引字段不是復合索引的前綴索引

? ? ? ?例如 在使用索引字段作為條件時,如果該索引是復合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統使用該索引,否則該索引將不會被使用,并且應盡可能的讓字段順序與索引順序相一致。


2 .其他一些注意優化:

12). 不要寫一些沒有意義的查詢,

? ? ? ? 如需要生成一個空表結構:

? ? ? ? select col1,col2 into #t from t where 1=0

? ? ? ? 這類代碼不會返回任何結果集,但是會消耗系統資源的,應改成這樣: create table #t(...)

13). 很多時候用 exists 代替 in 是一個好的選擇:

? ? ? ?select num from a where num in(select num from b)

? ? ? ?用下面的語句替換:

? ? ? ?select num from a where exists(select 1 from b where num=a.num)

14). 并不是所有索引對查詢都有效,

? ? ? ?SQL是根據表中數據來進行查詢優化的,當索引列有大量數據重復時,SQL查詢可能不會去利用索引,如一表中有字段sex,male、female幾乎各一半,那么即使在sex上建了索引也對查詢效率起不了作用。

15). 索引并不是越多越好,

? ? ? ?索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。

16).應盡可能的避免更新 clustered 索引數據列,

? ? ? ?因為 clustered 索引數據列的順序就是表記錄的物理存儲順序,一旦該列值改變將導致整個表記錄的順序的調整,會耗費相當大的資源。若應用系統需要頻繁更新 clustered 索引數據列,那么需要考慮是否應將該索引建為 clustered 索引。

17).盡量使用數字型字段,

? ? ? 若只含數值信息的字段盡量不要設計為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。這是因為引擎在處理查詢和連接時會逐個比較字符串中每一個字符,而對于數字型而言只需要比較一次就夠了。

18).盡可能的使用 varchar/nvarchar 代替 char/nchar ,

? ? ? 因為首先變長字段存儲空間小,可以節省存儲空間,其次對于查詢來說,在一個相對較小的字段內搜索效率顯然要高些。

19).最好不要使用"*"返回所有: select * from t ,

? ? ?用具體的字段列表代替“*”,不要返回用不到的任何字段。

3. 臨時表的問題:

20). 盡量使用表變量來代替臨時表。

? ? 如果表變量包含大量數據,請注意索引非常有限(只有主鍵索引)。?

21).避免頻繁創建和刪除臨時表,以減少系統表資源的消耗。

22).臨時表并不是不可使用,

? ? ?適當地使用它們可以使某些例程更有效,例如,當需要重復引用大型表或常用表中的某個數據集時。但是,對于一次性事件,最好使用導出表。

23).在新建臨時表時,如果一次性插入數據量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;

? ? ?如果數據量不大,為了緩和系統表的資源,應先create table,然后insert。

24). 如果使用到了臨時表,在存儲過程的最后務必將所有的臨時表顯式刪除,先 truncate table ,然后 drop table ,這樣可以避免系統表的較長時間鎖定。

4. 游標的問題:

25).盡量避免使用游標,

? ? ? 因為游標的效率較差,如果游標操作的數據超過1萬行,那么就應該考慮改寫。?

26).使用基于游標的方法或臨時表方法之前,

? ? ? 應先尋找基于集的解決方案來解決問題,基于集的方法通常更有效。

27).與臨時表一樣,游標并不是不可使用。

? ? ?對小型數據集使用 FAST_FORWARD 游標通常要優于其他逐行處理方法,尤其是在必須引用幾個表才能獲得所需的數據時。在結果集中包括“合計”的例程通常要比使用游標執行的速度快。如果開發時間允許,基于游標的方法和基于集的方法都可以嘗試一下,看哪一種方法的效果更好。

28).在所有的存儲過程和觸發器的開始處設置 SET NOCOUNT ON ,在結束時設置 SET NOCOUNT OFF 。

? ? ? 無需在執行存儲過程和觸發器的每個語句后向客戶端發送 DONE_IN_PROC 消息。

5. 事務的問題:

29).盡量避免大事務操作,提高系統并發能力。

6.?數據量的問題

30).盡量避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理。


7. COUNT優化:

31)?count(*) 優于count(1)和count(primary_key)

  很多人為了統計記錄條數,就使用?count(1)?和?count(primary_key)?而不是?count(*)?,他們認為這樣性能更好,其實這是一個誤區。對于有些場景,這樣做可能性能會更差,應為數據庫對?count(*)?計數操作做了一些特別的優化。

32)count(column)?和?count(*)?是不一樣的

  這個誤區甚至在很多的資深工程師或者是?DBA?中都普遍存在,很多人都會認為這是理所當然的。實際上,count(column)?和?count(*)?是一個完全不一樣的操作,所代表的意義也完全不一樣。

  count(column)?是表示結果集中有多少個column字段不為空的記錄

  count(*)?是表示整個結果集有多少條記錄

?


1)innodb引擎在統計方面和myisam是不同的,Myisam內置了一個計數器,

?Count(*)在沒有查詢條件的情況下使用 select count(*) from table 的時候,Myisam直接可以從計數器中取出數據。而innodb必須全表掃描一次方能得到總的數量

2. 但是當有查詢條件的時候,兩者的查詢效率一致。

4. 主鍵索引count(*)的時候之所以慢

InnoDB引擎:

[1]?????數據文件和索引文件存儲在一個文件中,主鍵索引默認直接指向數據存儲位置。

[2]?????二級索引存儲指定字段的索引,實際的指向位置是主鍵索引。當我們通過二級索引統計數據的時候,無需掃描數據文件;而通過主鍵索引統計數據時,由于主鍵索引與數據文件存放在一起,所以每次都會掃描數據文件,所以主鍵索引統計沒有二級索引效率高。

[3]?????由于主鍵索引直接指向實際數據,所以當我們通過主鍵id查詢數據時要比通過二級索引查詢數據要快。

l??MyAsm引擎

[1]?????該引擎把每個表都分為幾部分存儲,比如用戶表,包含user.frm,user.MYD和user.MYI。

[2]?????User.frm負責存儲表結構

[3]?????User.MYD負責存儲實際的數據記錄,所有的用戶記錄都存儲在這個文件中

[4]?????User.MYI負責存儲用戶表的所有索引,這里也包括主鍵索引。


?

8. 優化order by語句

? ? ?基于索引的排序
? ? ?MySQL的弱點之一是它的排序。雖然MySQL可以在1秒中查詢大約15,000條記錄,但由于MySQL在查詢時最多只能使用一個索引。因此,如果WHERE條件已經占用了索引,那么在排序中就不使用索引了,這將大大降低查詢的速度。我們可以看看如下的SQL語句:
? ? ?SELECT * FROM SALES WHERE NAME = “name” ORDER BY SALE_DATE DESC;
的WHERE子句中已經使用了NAME字段上的索引,因此,在對SALE_DATE進行排序時將不再使用索引。為了解決這個問題,我們可以對SALES表建立復合索引:
? ? ?ALTER TABLE SALES DROP INDEX NAME, ADD INDEX (NAME,SALE_DATE)
? ? ?這樣再使用上述的SELECT語句進行查詢時速度就會大副提升。但要注意,在使用這個方法時,要確保WHERE子句中沒有排序字段,在上例中就是不能用SALE_DATE進行查詢,否則雖然排序快了,但是SALE_DATE字段上沒有單獨的索引,因此查詢又會慢下來。

? ? ?在某些情況中, MySQL可以使用一個索引來滿足 ORDER BY子句,而不需要額外的排序。 where條件和order by使用相同的索引,并且order by 的順序和索引順序相 同,并且order by的字段都是升序或者都是降序。例如:下列sql可以使用索引。

? ? ?SELECT * FROM t1 ORDER BY key_part1,key_part2,... ;
? ? ?SELECT * FROM t1 WHERE key_part1=1 ORDER BY key_part1 DESC, key_part2?DESC;
? ? ?SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 DESC;
? ? 但是以下情況不使用索引:
? ? ?SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC ;?--order by 的字段混合 ASC 和 DESC
? ? ?SELECT * FROM t1 WHERE key2=constant ORDER BY key1 ;-- 用于查詢行的關鍵字與 ORDER BY 中所使用的不相同
? ? ?SELECT * FROM t1 ORDER BY key1, key2 ;-- 對不同的關鍵字使用 ORDER BY :




9. 優化GROUP BY

? ? ? 默認情況下, MySQL 排序所有 GROUP BY col1 , col2 , .... 。查詢的方法如同在查詢中指定 ORDER BY col1 , col2 , ... 。如果顯式包括一個包含相同的列的 ORDER BY
子句, MySQL 可以毫不減速地對它進行優化,盡管仍然進行排序。如果查詢包括 GROUP BY 但你想要避免排序結果的消耗,你可以指定 ORDER BY NULL禁止排序。
例如 :
INSERT INTO foo ?SELECT a, COUNT(*) FROM bar GROUP BY a ORDER BY NULL;


10. 優化 OR

具體詳解看:mysql or條件可以使用索引而避免全表?

?

4. Explain解釋說明

explain顯示了mysql如何使用索引來處理select語句以及連接表。可以幫助選擇更好的索引和寫出更優化的查詢語句。?
使用方法,在select語句前加上explain就可以了:?
如:

  1. explain?select?surname,first_name?form?a,b?where?a.id=b.id???
分析結果形式如下:?
table?|??type?|?possible_keys?|?key?|?key_len ?|?ref | rows?|?Extra?
EXPLAIN列的解釋
:?

1 table:

顯示這一行的數據是關于哪張表的?

2 type:

這是重要的列,顯示連接使用了何種類型。從最好到最差的連接類型為:system、const、eg_reg、ref、ref_or_null、?range、indexhe、?ALL。
? ? ? ? system:表僅有一行(=系統表)。這是const聯接類型的一個特例
? ? ??? const:(PRIMARY KEY或UNIQUE)
? ? ? ? ? ? 表最多有一個匹配行,它將在查詢開始時被讀取。因為僅有一行,在這行的列值可被優化器剩余部分認為是常數。
? ? ? ? ? ? const表很快,因為它們只讀取一次!
? ? ? ? ? ? const用于用常數值比較PRIMARY KEY或UNIQUE索引的所有部分時。
? ? ? ? ? ? 在下面的查詢中,tbl_name可以用于const表:
  1. SELECT?*?from?tbl_name?WHERE?primary_key=1;??
?eq_reg:key
? 對于每個來自于前面的表的行組合,從該表中讀取一行。這可能是最好的聯接類型,除了const類型。
? ? ? ? ? ?它用在一個索引的所有部分被聯接使用并且索引是UNIQUE或PRIMARY KEY。
? ? ? ? ? ?eq_ref可以用于使用= 操作符比較的帶索引的列。比較值可以為常量或一個使用在該表前面所讀取的表的列的表達式。
? 在下面的例子中,MySQL可以使用eq_ref聯接來處理ref_tables:
  1. SELECT?*?FROM?ref_table,other_table?WHERE?ref_table.key_column=other_table.column;??
  2. ???SELECT?*?FROM?ref_table,other_table?WHERE?ref_table.key_column_part1=other_table.column??
  3. ?????????????????????????????????????????????????AND?ref_table.key_column_part2=1;??

? ? ????ref:key
?對于每個來自于前面的表的行組合,所有有匹配索引值的行將從這張表中讀取。如果聯接只使用鍵的最左邊的前綴,
? ? ? ? ? 或如果鍵不是UNIQUE或PRIMARY KEY(換句話說,如果聯接不能基于關鍵字選擇單個行的話),則使用ref。
? ? ? ? ? 如果使用的鍵僅僅匹配少量行,該聯接類型是不錯的。
? ? ? ? ? ref可以用于使用=或<=>操作符的帶索引的列。
?在下面的例子中,MySQL可以使用ref聯接來處理ref_tables:
  1. SELECT?*?FROM?ref_table?WHERE?key_column=expr;??
  2. ?SELECT?*?FROM?ref_table,other_table?WHERE?ref_table.key_column=other_table.column;??
  3. ?SELECT?*?FROM?ref_table,other_table?WHERE?ref_table.key_column_part1=other_table.column??
  4. ??????????????????????????AND?ref_table.key_column_part2=1;??
? ? ??ref_or_null:Or Is null
該聯接類型如同ref,但是添加了MySQL可以專門搜索包含NULL值的行。在解決子查詢中經常使用該聯接類型的優化。
? ? ? ? 在下面的例子中,MySQL可以使用ref_or_null聯接來處理ref_tables:
  1. SELECT?*?FROM?ref_table?WHERE?key_column=expr?OR?key_column?IS?NULL;??????
? ??? range:=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN
?只檢索給定范圍的行,使用一個索引來選擇行。key列顯示使用了哪個索引。
? ? ? ? ? key_len包含所使用索引的最長關鍵元素。在該類型中ref列為NULL。
當使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比較關鍵字列時,可以使用range:
  1. SELECT?*?FROM?tbl_name?WHERE?key_column?=?10;??
  2. SELECT?*?FROM?tbl_name?WHERE?key_column?BETWEEN?10?and?20;??
  3. SELECT?*?FROM?tbl_name?WHERE?key_column?IN?(10,20,30);??
  4. SELECT?*?FROM?tbl_name?WHERE?key_part1=?10?AND?key_part2?IN?(10,20,30);??
? ??? indexhe:
該聯接類型與ALL相同,除了只有索引樹被掃描。這通常比ALL快,因為索引文件通常比數據文件小。
當查詢只使用作為單索引一部分的列時,MySQL可以使用該聯接類型。
? ? ??ALL:
對于每個來自于先前的表的行組合,進行完整的表掃描。如果表是第一個沒標記const的表,
? ? ? ? 這通常不好,并且通常在它情況下很差。通常可以增加更多的索引而不要使用ALL,
? ? ? ? 使得行能基于前面的表中的常數值或列值被檢索出。

3 possible_keys :

? ?顯示可能應用在這張表中的索引。如果為空,沒有可能的索引。可以為相關的域從WHERE語句中
? ?選擇一個合適的語句?

4 key :

?實際使用的索引。如果為NULL,則沒有使用索引。很少的情況下,MYSQL會選擇優化不足的索引 。
?這種情況下,可以在SELECT語句中使用USEINDEX(indexname)來強制使用一個索引或者用IGNORE INDEX(indexname)來強制MYSQL忽略索引?

5key_len:

使用的索引的長度。在不損失精確性的情況下,長度越短越好?

6 ref?

顯示索引的哪一列被使用了,如果可能的話,是一個常數?

7 rows?

MYSQL認為必須檢查的用來返回請求數據的行數 (掃描行的數量)

8 Extra?

?該列包含MySQL解決查詢的詳細信息
?關于MYSQL如何解析查詢的額外信息。將在表4.3中討論,但這里可以看到的壞的例子是Using temporary和Using filesort,
?意思MYSQL根本不能使用索引,結果是檢索會很慢?

extra列返回的描述的意義?

Distinct:
一旦MYSQL找到了與行相聯合匹配的行,就不再搜索了?
Not exists :
MYSQL優化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標準的行, 就不再搜索了?
? ? ? ? 面是一個可以這樣優化的查詢類型的例子:
SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;
假定t2.id定義為NOT NULL。在這種情況下,MySQL使用t1.id的值掃描t1并查找t2中的行。
? ? ? ? 如果MySQL在t2中發現一個匹配的行,它知道t2.id絕不會為NULL,并且不再掃描t2內有相同的id值的行。
? ? ? ? 換句話說,對于t1的每個行,MySQL只需要在t2中查找一次,無論t2內實際有多少匹配的行。
Range checked for each Record(index map:#)?
沒有找到理想的索引,因此對于從前面表中來的每一個行組合,MYSQL檢查使用哪個索引,并用它來從表中返回行。
? ? ? ? 這是使用索引的最慢的連接之一?
? ? ? ? MySQL沒有發現好的可以使用的索引,但發現如果來自前面的表的列值已知,可能部分索引可以使用。
? ? ? ? 對前面的表的每個行組合,MySQL檢查是否可以使用range或index_merge訪問方法來索取行。
? ? ? ? 關于適用性標準的描述參見7.2.5節,“范圍優化”和7.2.6節,“索引合并優化”,
? ? ? ? 不同的是前面表的所有列值已知并且認為是常量。這并不很快,但比執行沒有索引的聯接要快得多。
Using filesort?
看到這個的時候,查詢就需要優化了。MYSQL需要進行額外的步驟來發現如何對返回的行排序。
? ? ? ? 它根據連接類型以及存儲排序鍵值和匹配條件的全部行的行指針來排序全部行?
Using index?
列數據是從僅僅使用了索引中的信息而沒有讀取實際的行動的表返回的,
? ? ? ? 這發生在對表的全部的請求列都是同一個索引的部分的時候?
Using temporary?
看到這個的時候,查詢需要優化了。這里,MYSQL需要創建一個臨時表來存儲結果,這通常發生在對不同的列集進行ORDER BY上,而不是GROUP BY上?
Using where
使用了WHERE從句來限制哪些行將與下一張表匹配或者是返回給用戶。如果不想返回表中的全部行,
? ? ? ? 并且連接類型ALL或index,這就會發生,或者是查詢有問題?
Impossible WHERE noticed after reading const table...

5. SQL核心語句(非常實用的幾個技巧)



1) 插入數據

批量插入:
  1. INSERT?mytable?(first_column,second_column,third_column)??
  2. VALUES?('some?data','some?more?data','yet?more?data')?,??
  3. VALUES?('some?data','some?more?data','yet?more?data')?,??
  4. VALUES?('some?data','some?more?data','yet?more?data')???

2).清空數據表

?

  1. TRUNCATE?TABLE??`mytable`??

注意:刪除表中的所有記錄,應使用TRUNCATE TABLE語句。注意這里為什么要用TRUNCATE TABLE語句代替DELETE語句:當你使用TRUNCATE TABLE語句時,記錄的刪除是不作記錄的。也就是說,這意味著TRUNCATE TABLE要比DELETE快得多。

3)用SELECT創建記錄和表

  INSERT語句與DELETE語句和UPDATE語句有一點不同,它一次只操作一個記錄。然而,有一個方法可以使INSERT 語句一次添加多個記錄。要作到這一點,你需要把INSERT語句與SELECT語句結合起來,象這樣:

?

  1. INSERT?mytable(first_column,second_column)??
  2. SELECT?another_first,another_second??FROM?anothertable?WHERE?another_first='Copy?Me!';??

  這個語句從anothertable拷貝記錄到mytable.只有表anothertable中字段another_first的值為'Copy Me!'的記錄才被拷貝。

  當為一個表中的記錄建立備份時,這種形式的INSERT語句是非常有用的。在刪除一個表中的記錄之前,你可以先用這種方法把它們拷貝到另一個表中。

  如果你需要拷貝整個表,你可以使用SELECT INTO語句。例如,下面的語句創建了一個名為newtable的新表,該表包含表mytable的所有數據:

?

  1. SELECT?*?INTO?newtable?FROM?mytable;??

  你也可以指定只有特定的字段被用來創建這個新表。要做到這一點,只需在字段列表中指定你想要拷貝的字段。另外,你可以使用WHERE子句來限制拷貝到新表中的記錄。下面的例子只拷貝字段second_columnd的值等于'Copy Me!'的記錄的first_column字段。

?

  1. SELECT?first_column?INTO?newtable??
  2. FROM?mytable??
  3. WHERE?second_column='Copy?Me!';??

  使用SQL修改已經建立的表是很困難的。例如,如果你向一個表中添加了一個字段,沒有容易的辦法來去除它。另外,如果你不小心把一個字段的數據類型給錯了,你將沒有辦法改變它。但是,使用本節中講述的SQL語句,你可以繞過這兩個問題。

  例如,假設你想從一個表中刪除一個字段。使用SELECT INTO語句,你可以創建該表的一個拷貝,但不包含要刪除的字段。這使你既刪除了該字段,又保留了不想刪除的數據。

  如果你想改變一個字段的數據類型,你可以創建一個包含正確數據類型字段的新表。創建好該表后,你就可以結合使用UPDATE語句和SELECT語句,把原來表中的所有數據拷貝到新表中。通過這種方法,你既可以修改表的結構,又能保存原有的數據。

轉載于:https://www.cnblogs.com/xifenglou/p/7261411.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/252199.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/252199.shtml
英文地址,請注明出處:http://en.pswp.cn/news/252199.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Halcon實現邊緣提取

一、邊緣提取 1、設置ROI興趣區域 2、快速二值化&#xff0c;并連接相鄰區域。 這樣做的目的是進一步減少目標區域&#xff0c;通過二值化將目標區域大概輪廓提取出來 3、提取最接近目標區域的輪廓 常用函數有boundary&#xff0c;gen_contour_region_xld 4、根據自己的需求提取…

軟件工程網絡15個人閱讀作業1 201521123038 游舒婷

軟件工程網絡15個人閱讀作業1 201521123038 游舒婷 1.博客園地址 sakurai3104 2.碼云地址 sakurai3104 3.閱讀與思考 &#xff08;1&#xff09;回想一下你初入大學時對網絡工程專業的暢想 當初你是如何做出選擇網絡工程專業的決定的&#xff1f; 填報志愿的時候&#xff0c;大…

18LaTeX學習系列之---LaTeX的參考文獻

目錄 目錄前言&#xff08;一&#xff09;簡單的參考文獻1.說明2.源代碼3.輸出效果&#xff08;二&#xff09;以文件管理的方式1.說明&#xff1a;2.源代碼&#xff1a;3.輸出效果&#xff08;三&#xff09;直接從源網站獲取1.說明&#xff12;.操作目錄 本系列是有關LaTeX的…

Vue 2.0 v-for 響應式key, index及item.id參數對v-bind:key值造成差異研究

Vue 2.0 v-for 響應式key, index及item.id參數對v-bind:key值造成差異研究 在github上閱覽README.md以獲得最佳閱讀體驗&#xff0c;點這里 v-for響應式key, index及item.id參數對v-bind:key值造成差異研究 實驗背景 通常情況下&#xff0c;我們渲染一個li列表&#xff0c;采用…

halcon edges_sub_pix算子

轉載http://blog.51cto.com/juwen/133003 介紹一下Canny算子&#xff1a; 使用累計直方圖計算兩個閥值。凡是大于高閥值的一定是邊緣&#xff1b; 凡是小于低閥值的一定不是邊緣&#xff1b;如果檢測結果大于低閥值但又小于高閥值&#xff0c;那就要看這個像素的鄰接像素中有…

Python 基礎(常用數據結構)

常用數據結構 1&#xff09;元組 元組是一種靜態的數據結構&#xff0c;無法修改&#xff0c;若要修改只能重新生成新的元組。 輸出結果&#xff1a; 元組元素的獲取是通過索引值去獲得的&#xff1b;例如上面的tup1[0]返回apple&#xff1b;另外你可以直接把tup1一次性賦給多個…

Java IO(二)——RandomAccessFile

一、RandomAccessFile RandomAccessFile類可以說是Java語言中功能最為豐富的文件訪問類&#xff0c;它提供了眾多的文件訪問方法。RandomAccessFile類支持"隨機訪問"方式&#xff0c;可以跳轉到文件的任意位置處讀寫數據。要訪問一個文件的時候&#xff0c;不想把文件…

halcon select_shape_xld按區域大小描繪xld

常用與對xld進行以面積、長、寬進行XLD的選擇操作。 select_shape_xld(XLD : SelectedXLD : Features, Operation, Min, Max : ) XLD&#xff1a;需要選擇的xld SelectedXLD:選擇后的xld Features:面積、長、高等 Operation&#xff1a;and、or等 Min&#xff1a;最小值門…

工業三防手持終端如何選

物聯宇手持終端作為工業級的數據采集器&#xff0c;目前[]()已廣泛應用在物流快遞、生產制造、零售、醫療、公共事業等領域。由于工業環境的復雜性&#xff0c;手持終端在惡劣的環境下作業&#xff0c;在性能、穩定性、電池耐用性上的要求都較高&#xff0c;同時還必須采用一些…

centos7 安裝python3

1.查看是否已經安裝Python CentOS 7.2 默認安裝了python2.7.5 因為一些命令要用它比如yum 它使用的是python2.7.5。 使用 python -V 命令查看一下是否安裝Python 然后使用命令 which python 查看一下Python可執行文件的位置 可見執行文件在/usr/bin/ 目錄下&#xff0c;切換到該…

centos svn 的搭建

一. SVN 簡介 Subversion(SVN) 是一個開源的版本控制系統, 也就是說 Subversion 管理著隨時間改變的數據。 這些數據放置在一個中央資料檔案庫(repository) 中。 這個檔案庫很像一個普通的文件服務器, 不過它會記住每一次文件的變動。 這樣你就可以把檔案恢復到舊的版本, 或是瀏…

halcon邊緣提取和檢測常用方法

轉自&#xff1a;http://blog.csdn.net/Bob_qiuxu/article/details/46924969 一、邊緣提取 1、設置ROI興趣區域 2、快速二值化&#xff0c;并連接相鄰區域。 這樣做的目的是進一步減少目標區域&#xff0c;通過二值化將目標區域大概輪廓提取出來 3、提取最接近目標區域的輪廓…

oracle sqlplus常用命令

轉自&#xff1a;https://www.cnblogs.com/wdx8927304/p/7927613.html 一、sys用戶和system用戶Oracle安裝會自動的生成sys用戶和system用戶(1)、sys用戶是超級用戶&#xff0c;具有最高權限&#xff0c;具有sysdba角色&#xff0c;有create database的權限&#xff0c;該用戶默…

使用css繪制小三角

<div style"width:0;height:0;overflow: hidden;border-top:4px solid transparent;border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:4px solid red; "></div>轉載于:https://www.cnblogs.com/boonook/p/8570442.h…

C#與halcon聯合開發——內存溢出

1.對所以的局部零時變量HObject類的使用前后都加Dispose(); 2.對全局的HObject類變量進行如下定義 HObject liveImage null;HObject ExpGet_liveImage(){return liveImage;}void ExpSet_liveImage(HObject obj){if (liveImage ! null)liveImage.Dispose();liveImage obj.Cop…

點擊跳轉到QQ聊天界面

<!--//需要添加好友驗證--><a href"tencent://message/?uinQQ號碼&Site&Menuyes"><img src"需要點擊的圖片" width"80"/></a><!--不需要添加好友驗證--><a href"tencent://message/?Menuyes&am…

學習React的一知半解

① 初探 HMTL的渲染過程 ? 這個結構化文本就是 HTML 文本&#xff0c; HTML 中的每個元素都對應 DOM中某個節點&#xff0c;這樣&#xff0c;因為 HTML 元素的逐級包含關系&#xff0c; DOM 節點自然就構成了一個樹形結構&#xff0c;稱為 DOM 樹 。 ? 瀏覽器為了渲染 HTML 格…

DataTable 轉為ListT集合

public static List<T> HubbleTableToList<T>(this DataTable dt) where T:Class{List<T> _list new List<T>();if (dt null) return _list;T model;foreach (DataRow dr in dt.Rows)//進行循環dataTable行數據{model Activator.CreateInstance<…

工業相機與鏡頭分辨率匹配

// 轉自 奧普特講述工業相機與鏡頭分辨率匹配的技術方案 隨著機器視覺行業的發展&#xff0c;為了更好的滿足廣大客戶選配合適鏡頭的需求&#xff0c;奧普特自動化科技有限公司為您簡述工業相機如何選配合適的鏡頭&#xff0c;以及在相機與鏡頭的分辨率匹配方面的技術方案。 …

微信分享

<?php /*** Description of WxShare*微信分享* author xinjun*/ namespace Controller\Wx;use Controller\Home\HomeBase; use Model\Wx\UserModel; use Model\Wx\TokenModel; use Framework\Net\Request;class WxShare extends HomeBase {public function __construct(){p…