MySQL語句優化技巧
1、應盡量避免在 where 子句中使用!=或操作符,否則將引擎放棄使用索引而進行全表掃描。
2、對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
3、應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num is null
可以在num上設置默認值0,確保表中num列沒有null值,然后這樣查詢:
select id from t where num=0
4、盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num=10 or num=20
可以這樣查詢:
select id from t where num=10
union all
select id from t where num=20
5、下面的查詢也將導致全表掃描:(不能前置百分號)
select id from t where name like '?c%'
若要提高效率,可以考慮全文檢索。
6、in 和 not in 也要慎用,否則會導致全表掃描,如:
select id from t where num in(1,2,3)
對于連續的數值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
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/2=100
應改為:
select id from t where num=100*2
9、應盡量避免在where子句中對字段進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。如:
select id from t where substring(name,1,3)='abc'–name以abc開頭的id
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
mysql中的sql語句怎樣優化
你的語句是正確的,速度慢兩種可能: 一、是索引不對,你所有的關聯字段,應該在相應表中有唯一索引,最好是主鍵,例如: cdb_* cdb_memberfields .uid supe_* cdb_*d cdb_*d supe_* supe_* 如果以上的表沒有主鍵,請設置相應字段為主鍵,如果有其他的主鍵而且是必須的,那么在上面的字段建立唯一索引。
二、數據量過大,如果你cdb_members的記錄很多,遠遠大于500條,可以考慮改變程序,先重此表里面獲取500條數據,然后在循環里面每條數據庫關聯獲取其它表的信息,這樣就不需要先對五個表做鏈接。
mysql 語句優化
從句子中可以看到,選取的字段比較多,另外連接條件也比較多,另外還包括了子查詢。
就此語句給出幾個需要注意的問題:
1、請先使用explain,對這個語句進行分析,EXPLAIN解釋SELECT命令如何被處理。這不僅對決定是否應該增加一個索引,而且對決定一個復雜的Join如何被MySQL處理都是有幫助的。
2、盡量在連接條件多的時候,把數據提取量少的條件放在前面,這樣會減少后一個條件的查詢時間。對了,這些經常用的連接條件最好建上索引。我不清楚
INNER JOIN table_user_profile AS up ON * = *
INNER JOIN table_user_count AS uc ON * = *
INNER JOIN table_user_daren AS ud ON * = *
這些那個先內連接數據比較少,自己排列一下試一試。
3、避免使用!=或、IS NULL或IS NOT NULL、IN ,NOT IN等這樣的操作符,因為這會使系統無法使用索引,而只能直接搜索表中的數據。像in和not in這樣的關鍵字用exists和not exists比較好。* not in(SELECT uid FROM table_user_follow where f_uid=100)改成* not exists(SELECT uid FROM table_user_follow where f_uid=100),效率會有提高。
4、mysql使用函數的時候會增加負擔,完全可以交給腳本程序去解決。比如此子查詢:
SELECT MAX(share_id) FROM table_share 完全可以不寫在這個sql語句中,交給腳本程序可以了。
怎樣優化SQL語句的執行
環境:oracle 817 + linux + 陣列柜 swd_billdetail 表5000萬條數據 SUPER_USER 表2800條數據 連接列上都有索引,而且super_user中的一條對應于swd_billdetail表中的很多條記錄表與索引都做了分析。
實際應用的查詢為: select a。CHANNEL, B。
user_class from swd_billdetail B, SUPER_USER A where A。cn = B。
cn; 這樣在分析時導致查詢出的數據過多,不方便,所以用count(a。 CHANNEL||B。
user_class)來代替,而且count(a。CHANNEL||B。
user_class)操作本身并不占用過多的時間,所以可以接受此種替代。 利用索引查詢出SWD_BILLDETAIL表中所有記錄的方法 SQL> select count(id) from SWD_BILLDETAIL; COUNT(ID) ---------- 53923574 Elapsed: 00:02:166。
00 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=18051 Card=1) 1 0 SORT (AGGREGATE) 2 1 INDEX (FAST FULL SCAN) OF 'SYS_C001851' (UNIQUE) (Cost=18051 Card=54863946) Statistics ---------------------------------------------------------- 0 recursive calls 1952 db block gets 158776 consistent gets 158779 physical reads 1004 redo size 295 bytes sent via SQL*Net to client 421 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 1 rows processed 利用全表掃描從SWD_BILLDETAIL表中取出全部數據的方法。 SQL> select count(user_class) from swd_billdetail; COUNT(USER_CLASS) ----------------- 53923574 Elapsed: 00:11:703。
07 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=165412 Card=1 Bytes=2) 1 0 SORT (AGGREGATE) 2 1 TABLE ACCESS (FULL) OF 'SWD_BILLDETAIL' (Cost=165412 Card=54863946 Bytes=109727892) Statistics ---------------------------------------------------------- 0 recursive calls 8823 db block gets 1431070 consistent gets 1419520 physical reads 0 redo size 303 bytes sent via SQL*Net to client 421 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 1 rows processed select count(a。 CHANNEL||B。
user_class) from swd_billdetail B, SUPER_USER A where A。cn = B。
cn; EXEC_ORDER PLANLINE ---------- ----------------------------------------------------------------------------------------------------------- 6 SELECT STATEMENT OPT_MODE:CHOOSE (COST=108968,CARD=1,BYTES=21) 5 SORT (AGGREGATE) (COST=,CARD=1,BYTES=21) 4 NESTED LOOPS (COST=108968,CARD=1213745,BYTES=25488645) 1 TABLE ACCESS (FULL) OF 'SWORD。 SUPER_USER' (COST=2,CARD=2794,BYTES=27940) 3 TABLE ACCESS (BY INDEX ROWID) OF 'SWORD。
SWD_BILLDETAIL' (COST=39,CARD=54863946,BYTES=603503406) 2 INDEX (RANGE SCAN) OF 'SWORD。 IDX_DETAIL_CN' (NON-UNIQUE) (COST=3,CARD=54863946,BYTES=) 這個查詢耗費的時間很長,需要1個多小時。
運行后的信息如下: COUNT(A。CHANNEL||B。
USER_CLASS) ------------------------------ 1186387 Elapsed: 01:107:6429。 87 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=108968 Card=1 Bytes=21) 1 0 SORT (AGGREGATE) 2 1 NESTED LOOPS (Cost=108968 Card=1213745 Bytes=25488645) 3 2 TABLE ACCESS (FULL) OF 'SUPER_USER' (Cost=2 Card=2794Bytes=27940) 4 2 TABLE ACCESS (BY INDEX ROWID) OF 'SWD_BILLDETAIL' (Cost=39 Card=54863946 Bytes=603503406) 5 4 INDEX (RANGE SCAN) OF 'IDX_DETAIL_CN' (NON-UNIQUE) (Cost=3 Card=54863946) Statistics ---------------------------------------------------------- 0 recursive calls 4 db block gets 1196954 consistent gets 1165726 physical reads 0 redo size 316 bytes sent via SQL*Net to client 421 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 2 sorts (memory) 0 sorts (disk) 1 rows processed 將語句中加入hints,讓oracle的優化器使用嵌套循環,并且大表作為驅動表,生成新的執行計劃: select /*+ ORDERED USE_NL(A) */ count(a。
CHANNEL||B。user_class) from swd_billdetail B, SUPER_USER A where A。
cn = B。cn; EXEC_ORDER PLANLINE ---------- ----------------------------------------------------------------------------------------------------- 6 SELECT STATEMENT OPT_MODE:CHOOSE (COST=109893304,CARD=1,BYTES=21) 5 SORT (AGGREGATE) (COST=,CARD=1,BYTES=21) 4 NESTED LOOPS (COST=109893304,CARD=1213745,BYTES=25488645) 1 TABLE ACCESS (FULL) OF 'SWORD。
SWD_BILLDETAIL' (COST=165412,CARD=54863946,BYTES=603503406) 3 TABLE ACCESS (BY INDEX ROWID) OF 'SWORD。SUPER_USER。
mysql數據庫怎么優化sql語句
一、MySQL數據庫有幾個配置選項可以幫助我們及時捕獲低效SQL語句
1,slow_query_log
這個參數設置為ON,可以捕獲執行時間超過一定數值的SQL語句。
2,long_query_time
當SQL語句執行時間超過此數值時,就會被記錄到日志中,建議設置為1或者更短。
3,slow_query_log_file
記錄日志的文件名。
4,log_queries_not_using_indexes
這個參數設置為ON,可以捕獲到所有未使用索引的SQL語句,盡管這個SQL語句有可能執行得挺快。
二、檢測mysql中sql語句的效率的方法
1、通過查詢日志
(1)、Windows下開啟MySQL慢查詢
MySQL在Windows系統中的配置文件一般是是*找到[mysqld]下面加上
代碼如下
log-slow-queries = F:/MySQL/log/mysqlslowquery。log
long_query_time = 2
(2)、Linux下啟用MySQL慢查詢
MySQL在Windows系統中的配置文件一般是是*找到[mysqld]下面加上
代碼如下
log-slow-queries=/data/mysqldata/slowquery。log
long_query_time=2
MYSQL查詢語句優化
SELECT info_list.* from info_list left join info_zhuanban on info_*o=info_*o where (info_*='0090' and info_* in(4,5) and info_*type in(1,3,4,5,7) ) or (info_*='0090' and info_*=5 and info_* in(4,5) and info_*type in(1,3,4,5,7) ) order by info_*time desc;。