mysqlsql語句優化
❶ 如何用一款小工具大大加速Mysql SQL語句優化
其實MySQL自帶查詢優化器啊。
explain SELECT id,name from tablename where id = 10;root@localhost [test]>explain select id,k from sbtest1 where id =1000\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: sbtest1 partitions: NULL type: constpossible_keys: PRIMARY key: PRIMARY key_len: 4 ref: const rows: 1 filtered: 100.00 Extra: NULL1 row in set, 1 warning (0.02 sec)這個就告訴你,這一條語句是如何執行的。possible_keys,只可能會走的索引key:是實際走的索引,這里走的是主鍵索引哈。sql優化還有很多知識,一般都用這個來查看執行計劃。具體細節你需要再去翻看資料。##基礎內容可以看看這里。使用MariaDB資料庫管理系統。#MariaDB和MySQL使用上大致一樣的。
❷ 請問這個MySQL SQL語句如何優化(改寫)
user_id和create_time的聯合索引並不會對按照user_id分組起作用,還是需要在user_id列上單獨創建一個索引,這樣group by子句可以使用該索引,where子句當中的條件也會用到該索引,查詢效率應該會得到顯著提升,不妨一試。
❸ mysql如何優化以下語句,查詢耗時太久了
一般進行性能分析,分如下三步:
首先需要使用慢查詢日誌功能,去獲取所有查詢時間比較長的SQL語句
其次查看執行計劃查看有問題的SQL的執行計劃 explain
最後可以使用show profile查看有問題的SQL的性能使用情況
慢查詢日誌分析
首先我們要使用慢查詢日誌,因為它收集了查詢時間比較長的SQL語句,但使用之前必須開啟慢查詢日誌,在配置文件my.cnf(一般為/etc/my.cnf)中的[mysqld] 增加如下參數:
slow_query_log=ONlong_query_time=3slow_query_log_file=/var/lib/mysql/slow-log.log復制代碼
增加這些參數之後,重啟MySQL,可以進行查詢慢查詢日誌是否開啟。
1. 任何地方都不要使用 select * from t,用具體的欄位列表代替「*「,不要返回用不到的任何欄位。
2. 索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。
3. 並不是所有索引對查詢都有效,SQL是根據表中數據來進行查詢優化的,當索引列有大量數據重復時,SQL查詢可能不會去利用索引,如一表中有欄位sex,male、female幾乎各一半,那麼即使在sex上建了索引也對查詢效率起不了作用。
4. 盡量使用數字型欄位,若只含數值信息的欄位盡量不要設計為字元型,這會降低查詢和連接的性能,並會增加存儲開銷。這是因為引擎在處理查詢和連接時會逐個比較字元串中每一個字元,而對於數字型而言只需要比較一次就夠了。
5. 盡可能的使用 varchar 代替 char ,因為首先變長欄位存儲空間小,可以節省存儲空間, 其次對於查詢來說,在一個相對較小的欄位內搜索效率顯然要高些。
6. 如果使用到了臨時表,在存儲過程的最後務必將所有的臨時表顯式刪除,先 truncate table ,然後 drop table ,這樣可以避免系統表的較長時間鎖定。
7. 對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where和order by相關的列上建立索引。
8. 應盡量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描。
例如: select * from t where num is null
我們可以在num上設置默認值0,確保表中num列沒有null值,然後這樣查詢:select * from t where num=0。
❹ mysql的sql語句優化5種方式
只有5種嗎?我知道十種以上的說。
索引(沒我得全表查詢了)
改變數據儲引擎(MyISAM沒事務再也不用擔心鎖表了)
增加冗餘數來減少連表查詢數(消耗硬碟空間減少CPU使用)
調整查詢順序減少查詢量優先(數量少了連表的笛卡兒積也少了)
全文索引(文字長度有限制,而且IO使用量會大增,但是妥妥的快)
查詢盡量不要用函數(函數可是不走索引的哦親)
查詢變數類型要提前對好減少系統負擔(我提前改變了系統你就不用檢測了)
升級伺服器硬體(沒什麼是氪金解決不了的)
配置好臨時表空間,合理理由臨時表減少主表查詢搶資源(唯我獨查)
合理理由函數減少系統的判斷(明明都能確認內容不同你用UNION 系統還是傻傻的查一遍是否重復UNION ALL則跳過這個步驟同理 inner join 和 left join 也一樣)
強制走索引(復合索引的情況有時候手動走比系統判斷要好哦)
臟讀、幻讀等(你堵車我繞路)
數據歸檔,遷移(沒用的數據要進倉哦,別占著主表的資源)
表的碎片整理(遷移後碎片整理更健康哦親)
索引重構(數據都走了索引也應該重構一下才能保證速度哦)
善用存儲過程(串N個表(N大於10)的查詢千萬別一個SQL到底,分布式查詢在吧結果集合並吧騷年)
預處理數據(mysql也有job哦,對於經常要子查詢的數據可以先弄個明細表根據主表在後台進行補完,查詢的時候就更方便了)
懶得說了。。。。。。。。。。。。。。。。。。
❺ mysql 求大神優化sql語句
可以這樣寫成只使用1個子查詢:
select a.* ,b.d as day_num,b.m as month_num,b.y as year_num
from watersku a,(select sum(b.num) as y,
sum(case when date_format(b.add_time,'%Y-%m')=date_format(now(),'%Y-%m')
then b.num else 0 end) as m,
sum(case when date_format(b.add_time,'%Y-%m-%d')=date_format(now(),'%Y-%m-%d')
then b.num else 0 end) as d
from tra_order b , tra_trade b0
where a.sku_id = b.sku_id and b.tids = b0.tid and b0.status > 2 and date_format(b.add_time,'%Y')=date_format(now(),'%Y'))b
另外上述按當前年、月、系統日期篩選比較表達式,也可以直接用year,month函數替代format函數進行比較,也許效率會高一些。
至於哪些寫法的效率高一點,很多時候實際情況與我們想像有較大差距,有時我們認為效率低的寫法執行效率並不會比我們認為高的寫法低很多,甚至有可能掉反過來,對於這一點我在實際工作中深有體會。穩妥一些的做法是查看SQL執行計劃,當然更為可靠的辦法是使用大數據表進行實測比較。
❻ mysql 優化包括哪些內容
mysql的優化大的有兩方面:
1、配置優化
配置的優化其實包含兩個方面的:操作系統內核的優化和mysql配置文件的優化
1)系統內核的優化對專用的mysql伺服器來說,無非是內存實用、連接數、超時處理、TCP處理等方面的優化,根據自己的硬體配置來進行優化,這里不多講;
2)mysql配置的優化,一般來說包含:IO處理的常用參數、最大連接數設置、緩存使用參數的設置、慢日誌的參數的設置、innodb相關參數的設置等,如果有主從關系在設置主從同步的相關參數即可,網上的相關配置文件很多,大同小異,常用的設置大多修改這些差不多就夠用了。
2、sql語句的優化
1、 盡量稍作計算
Mysql的作用是用來存取數據的,不是做計算的,做計算的話可以用其他方法去實現,mysql做計算是很耗資源的。
2.盡量少 join
MySQL 的優勢在於簡單,但這在某些方面其實也是其劣勢。MySQL 優化器效率高,但是由於其統計信息的量有限,優化器工作過程出現偏差的可能性也就更多。對於復雜的多表 Join,一方面由於其優化器受限,再者在 Join 這方面所下的功夫還不夠,所以性能表現離 Oracle 等關系型資料庫前輩還是有一定距離。但如果是簡單的單表查詢,這一差距就會極小甚至在有些場景下要優於這些資料庫前輩。
3.盡量少排序
排序操作會消耗較多的 CPU 資源,所以減少排序可以在緩存命中率高等 IO 能力足夠的場景下會較大影響 SQL的響應時間。
對於MySQL來說,減少排序有多種辦法,比如:
通過利用索引來排序的方式進行優化
減少參與排序的記錄條數
非必要不對數據進行排序
4.盡量避免 select *
在數據量少並且訪問量不大的情況下,select * 沒有什麼影響,但是量級達到一定級別的時候,在執行效率和IO資源的使用上,還是有很大關系的,用什麼欄位取什麼欄位,減少不必要的資源浪費。
之前遇到過因為一個欄位存儲的數據比較大,並發高的情況下把網路帶寬跑滿的情況,造成網站打不開或是打開速度極慢的情況。
5.盡量用 join 代替子查詢
雖然 Join 性能並不佳,但是和 MySQL 的子查詢比起來還是有非常大的性能優勢。MySQL 的子查詢執行計劃一直存在較大的問題,雖然這個問題已經存在多年,但是到目前已經發布的所有穩定版本中都普遍存在,一直沒有太大改善。雖然官方也在很早就承認這一問題,並且承諾盡快解決,但是至少到目前為止我們還沒有看到哪一個版本較好的解決了這一問題。
6.盡量少 or
當 where 子句中存在多個條件以「或」並存的時候,MySQL 的優化器並沒有很好的解決其執行計劃優化問題,再加上 MySQL 特有的 SQL 與 Storage 分層架構方式,造成了其性能比較低下,很多時候使用 union all 或者是union(必要的時候)的方式來代替「or」會得到更好的效果。
7.盡量用 union all 代替 union
union 和 union all 的差異主要是前者需要將兩個(或者多個)結果集合並後再進行唯一性過濾操作,這就會涉及到排序,增加大量的 CPU 運算,加大資源消耗及延遲。所以當我們可以確認不可能出現重復結果集或者不在乎重復結果集的時候,盡量使用 union all 而不是 union。
8.盡量早過濾
這一優化策略其實最常見於索引的優化設計中(將過濾性更好的欄位放得更靠前)。
在 SQL 編寫中同樣可以使用這一原則來優化一些 Join 的 SQL。比如我們在多個表進行分頁數據查詢的時候,我們最好是能夠在一個表上先過濾好數據分好頁,然後再用分好頁的結果集與另外的表 Join,這樣可以盡可能多的減少不必要的 IO 操作,大大節省 IO 操作所消耗的時間。
9.避免類型轉換
這里所說的「類型轉換」是指 where 子句中出現 column 欄位的類型和傳入的參數類型不一致的時候發生的類型轉換:
A:人為在column_name 上通過轉換函數進行轉換
直接導致 MySQL(實際上其他資料庫也會有同樣的問題)無法使用索引,如果非要轉換,應該在傳入的參數上進行轉換
B:由資料庫自己進行轉換
如果我們傳入的數據類型和欄位類型不一致,同時我們又沒有做任何類型轉換處理,MySQL 可能會自己對我們的數據進行類型轉換操作,也可能不進行處理而交由存儲引擎去處理,這樣一來,就會出現索引無法使用的情況而造成執行計劃問題。
以上兩種情況在開發者因為某種原因經常會有,本來可以用到索引的結果類型不對沒有用到索引,或是因為類型不對又有越界的情況發生造成無法使用索引的情況,結果造成很嚴重的事故。
10.優先優化高並發的 SQL,而不是執行頻率低某些「大」SQL
對於破壞性來說,高並發的 SQL 總是會比低頻率的來得大,因為高並發的 SQL 一旦出現問題,甚至不會給我們任何喘息的機會就會將系統壓跨。而對於一些雖然需要消耗大量 IO 而且響應很慢的 SQL,由於頻率低,即使遇到,最多就是讓整個系統響應慢一點,但至少可能撐一會兒,讓我們有緩沖的機會。
11.從全局出發優化,而不是片面調整
SQL 優化不能是單獨針對某一個進行,而應充分考慮系統中所有的 SQL,尤其是在通過調整索引優化 SQL 的執行計劃的時候,千萬不能顧此失彼,因小失大。
12.盡可能對每一條運行在資料庫中的SQL進行 explain
優化 SQL,需要做到心中有數,知道SQL 的執行計劃才能判斷是否有優化餘地,才能判斷是否存在執行計劃問題。在對資料庫中運行的 SQL 進行了一段時間的優化之後,很明顯的問題 SQL 可能已經很少了,大多都需要去發掘,這時候就需要進行大量的 explain 操作收集執行計劃,並判斷是否需要進行優化。
❼ mysql如何優化以下語句,查詢耗時太久了
根據所描述的問題,可嘗試在mms_profitcenter 的FOrderID ,FSuffix列上建立索引,再查詢試試。 下面提供30種mysql常用優化方法供參考:
1.對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
2.應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。
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 '%abc%'
若要提高效率,可以考慮全文檢索。
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<'2005-12-1'
10.不要在 where 子句中的「=」左邊進行函數、算術運算或其他表達式運算,否則系統將可能無法正確使用索引。
11.在使用索引欄位作為條件時,如果該索引是復合索引,那麼必須使用到該索引中的第一個欄位作為條件時才能保證系統使用該索引,否則該索引將不會被使用,並且應盡可能的讓欄位順序與索引順序相一致。
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 ,用具體的欄位列表代替「*」,不要返回用不到的任何欄位。
20.盡量使用表變數來代替臨時表。如果表變數包含大量數據,請注意索引非常有限(只有主鍵索引)。
21.避免頻繁創建和刪除臨時表,以減少系統表資源的消耗。
22.臨時表並不是不可使用,適當地使用它們可以使某些常式更有效,例如,當需要重復引用大型表或常用表中的某個數據集時。但是,對於一次性事件,最好使用導出表。
23.在新建臨時表時,如果一次性插入數據量很大,那麼可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果數據量不大,為了緩和系統表的資源,應先create table,然後insert。
24.如果使用到了臨時表,在存儲過程的最後務必將所有的臨時表顯式刪除,先 truncate table ,然後 drop table ,這樣可以避免系統表的較長時間鎖定。
25.盡量避免使用游標,因為游標的效率較差,如果游標操作的數據超過1萬行,那麼就應該考慮改寫。
26.使用基於游標的方法或臨時表方法之前,應先尋找基於集的解決方案來解決問題,基於集的方法通常更有效。
27.與臨時表一樣,游標並不是不可使用。對小型數據集使用 FAST_FORWARD 游標通常要優於其他逐行處理方法,尤其是在必須引用幾個表才能獲得所需的數據時。在結果集中包括「合計」的常式通常要比使用游標執行的速度快。如果開發時間允許,基於游標的方法和基於集的方法都可以嘗試一下,看哪一種方法的效果更好。
28.在所有的存儲過程和觸發器的開始處設置 SET NOCOUNT ON ,在結束時設置 SET NOCOUNT OFF 。無需在執行存儲過程和觸發器的每個語句後向客戶端發送 DONE_IN_PROC 消息。
29.盡量避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理。
30.盡量避免大事務操作,提高系統並發能力。