導航:首頁 > IDC知識 > mysql伺服器優化

mysql伺服器優化

發布時間:2021-02-04 08:20:43

1、Mysql伺服器如何得到最佳性能優化

為查詢緩復存優化你的制查詢 2. EXPLAIN 你的 SELECT 查詢 

3. 當只要一行數據時使用 LIMIT 1 

4. 為搜索欄位建索引 
5. 在Join表的時候使用相當類型的例,並將其索引 
6. 千萬不要 ORDER BY RAND() 

7. 避免 SELECT * 

8. 永遠為每張表設置一個ID 
9. 使用 ENUM 而不是 VARCHAR 
10. 從 PROCEDURE ANALYSE() 取得建議 
11. 盡可能的使用 NOT NULL 
12. Prepared Statements 
13. 無緩沖的查詢 

14. 把IP地址存成 UNSIGNED INT 
15. 固定長度的表會更快 
16. 垂直分割 
17. 拆分大的 DELETE 或 INSERT 語句 

18. 越小的列會越快 
19. 選擇正確的存儲引擎 
20. 使用一個對象關系映射器(Object Relational Mapper) 
21. 小心「永久鏈接」 

2、mysql伺服器讀取速度優化

關於mysql處理百萬級以上的數據時如何提高其查詢速度的方法

最近一段時間由於工作需要,開始關注針對Mysql資料庫的select查詢語句的相關優化方法。

由於在參與的實際項目中發現當mysql表的數據量達到百萬級時,普通SQL查詢效率呈直線下降,而且如果where中的查詢條件較多時,其查詢速度簡直無法容忍。曾經測試對一個包含400多萬條記錄(有索引)的表執行一條條件查詢,其查詢時間竟然高達40幾秒,相信這么高的查詢延時,任何用戶都會抓狂。因此如何提高sql語句查詢效率,顯得十分重要。以下是網上流傳比較廣泛的30種SQL查詢語句優化方法:
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<』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、盡量避免大事務操作,提高系統並發能力。

3、怎樣優化「mysql資料庫」來提高「mysql性能」?

優化「mysql資料庫」來提高「mysql性能」的方法有:

1、選取最適用的欄位屬性。

MySQL可以很好的支持大數據量的存取,但是一般說來,資料庫中的表越小,在它上面執行的查詢也就會越快。因此,在創建表的時候,為了獲得更好的性能,我們可以將表中欄位的寬度設得盡可能小。

2、使用連接(JOIN)來代替子查詢(Sub-Queries)。

MySQL從4.1開始支持SQL的子查詢。這個技術可以使用SELECT語句來創建一個單列的查詢結果,然後把這個結果作為過濾條件用在另一個查詢中。

3、使用聯合(UNION)來代替手動創建的臨時表。  

MySQL 從4.0的版本開始支持UNION查詢,它可以把需要使用臨時表的兩條或更多的SELECT查詢合並的一個查詢中。在客戶端的查詢會話結束的時候,臨時表會被自動刪除,從而保證資料庫整齊、高效。

4、事務。

要把某個數據同時插入兩個相關聯的表中,可能會出現這樣的情況:第一個表中成功更新後,資料庫突然出現意外狀況,造成第二個表中的操作沒有完成,這樣,就會造成數據的不完整,甚至會破壞資料庫中的數據。要避免這種情況,就應該使用事務,它的作用是:要麼語句塊中每條語句都操作成功,要麼都失敗。

5、鎖定表。

盡管事務是維護資料庫完整性的一個非常好的方法,但卻因為它的獨占性,有時會影響資料庫的性能,尤其是在很大的應用系統中。由於在事務執行的過程中,資料庫將會被鎖定,因此其它的用戶請求只能暫時等待直到該事務結束。

6、使用外鍵。

鎖定表的方法可以維護數據的完整性,但是它卻不能保證數據的關聯性。這個時候我們就可以使用外鍵。

7、使用索引 

索引是提高資料庫性能的常用方法,它可以令資料庫伺服器以比沒有索引快得多的速度檢索特定的行,尤其是在查詢語句當中包含有MAX(), MIN()和ORDERBY這些命令的時候,性能提高更為明顯。

8、優化的查詢語句 

絕大多數情況下,使用索引可以提高查詢的速度,但如果SQL語句使用不恰當的話,索引將無法發揮它應有的作用。

4、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 操作收集執行計劃,並判斷是否需要進行優化。

5、如何對mysql伺服器進行調優

1、選取最適用的欄位屬性

MySQL 可以很好的支持大數據量的存取,但是一般說來,資料庫中的表越小,在它上面執行的查詢也就會越快。因此,在創建表的時候,為了獲得更好的性能,我們可以將表中欄位的寬度設得盡可能小。例如,在定義郵政編碼這個欄位時,如果將其設置為CHAR(255),顯然給資料庫增加了不必要的空間,甚至使用VARCHAR這種類型也是多餘的,因為CHAR(6)就可以很好的完成任務了。同樣的,如果可以的話,我們應該使用MEDIUMINT而不是BIGIN來定義整型欄位。

另外一個提高效率的方法是在可能的情況下,應該盡量把欄位設置為NOT NULL,這樣在將來執行查詢的時候,資料庫不用去比較NULL值。

對於某些文本欄位,例如「省份」或者「性別」,我們可以將它們定義為ENUM類型。因為在MySQL中,ENUM類型被當作數值型數據來處理,而數值型數據被處理起來的速度要比文本類型快得多。這樣,我們又可以提高資料庫的性能。

2、使用連接(JOIN)來代替子查詢(Sub-Queries)

MySQL 從4.1開始支持SQL的子查詢。這個技術可以使用SELECT語句來創建一個單列的查詢結果,然後把這個結果作為過濾條件用在另一個查詢中。例如,我們要將客戶基本信息表中沒有任何訂單的客戶刪除掉,就可以利用子查詢先從銷售信息表中將所有發出訂單的客戶ID取出來,然後將結果傳遞給主查詢,如下所示:

DELETE FROM customerinfo
WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo )

使用子查詢可以一次性的完成很多邏輯上需要多個步驟才能完成的SQL操作,同時也可以避免事務或者表鎖死,並且寫起來也很容易。但是,有些情況下,子查詢可以被更有效率的連接(JOIN).. 替代。例如,假設我們要將所有沒有訂單記錄的用戶取出來,可以用下面這個查詢完成:

SELECT * FROM customerinfo
WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo )

如果使用連接(JOIN).. 來完成這個查詢工作,速度將會快很多。尤其是當salesinfo表中對CustomerID建有索引的話,性能將會更好,查詢如下:

SELECT * FROM customerinfo
LEFT JOIN salesinfoON customerinfo.CustomerID=salesinfo.
CustomerID
WHERE salesinfo.CustomerID IS NULL

連接(JOIN).. 之所以更有效率一些,是因為 MySQL不需要在內存中創建臨時表來完成這個邏輯上的需要兩個步驟的查詢工作。

3、使用聯合(UNION)來代替手動創建的臨時表

MySQL 從 4.0 的版本開始支持 UNION 查詢,它可以把需要使用臨時表的兩條或更多的 SELECT 查詢合並的一個查詢中。在客戶端的查詢會話結束的時候,臨時表會被自動刪除,從而保證資料庫整齊、高效。使用 UNION 來創建查詢的時候,我們只需要用 UNION作為關鍵字把多個 SELECT 語句連接起來就可以了,要注意的是所有 SELECT 語句中的欄位數目要想同。下面的例子就演示了一個使用 UNION的查詢。

SELECT Name, Phone FROM client
UNION
SELECT Name, BirthDate FROM author
UNION
SELECT Name, Supplier FROM proct

4、事務

盡管我們可以使用子查詢(Sub-Queries)、連接(JOIN)和聯合(UNION)來創建各種各樣的查詢,但不是所有的資料庫操作都可以只用一條或少數幾條SQL語句就可以完成的。更多的時候是需要用到一系列的語句來完成某種工作。但是在這種情況下,當這個語句塊中的某一條語句運行出錯的時候,整個語句塊的操作就會變得不確定起來。設想一下,要把某個數據同時插入兩個相關聯的表中,可能會出現這樣的情況:第一個表中成功更新後,資料庫突然出現意外狀況,造成第二個表中的操作沒有完成,這樣,就會造成數據的不完整,甚至會破壞資料庫中的數據。要避免這種情況,就應該使用事務,它的作用是:要麼語句塊中每條語句都操作成功,要麼都失敗。換句話說,就是可以保持資料庫中數據的一致性和完整性。事物以BEGIN 關鍵字開始,COMMIT關鍵字結束。在這之間的一條SQL操作失敗,那麼,ROLLBACK命令就可以把資料庫恢復到BEGIN開始之前的狀態。

BEGIN;
INSERT INTO salesinfo SET CustomerID=14;
UPDATE inventory SET Quantity=11
WHERE item='book';
COMMIT;

事務的另一個重要作用是當多個用戶同時使用相同的數據源時,它可以利用鎖定資料庫的方法來為用戶提供一種安全的訪問方式,這樣可以保證用戶的操作不被其它的用戶所干擾。

5、鎖定表

盡管事務是維護資料庫完整性的一個非常好的方法,但卻因為它的獨占性,有時會影響資料庫的性能,尤其是在很大的應用系統中。由於在事務執行的過程中,資料庫將會被鎖定,因此其它的用戶請求只能暫時等待直到該事務結束。如果一個資料庫系統只有少數幾個用戶

來使用,事務造成的影響不會成為一個太大的問題;但假設有成千上萬的用戶同時訪問一個資料庫系統,例如訪問一個電子商務網站,就會產生比較嚴重的響應延遲。

其實,有些情況下我們可以通過鎖定表的方法來獲得更好的性能。下面的例子就用鎖定表的方法來完成前面一個例子中事務的功能。

LOCK TABLE inventory WRITE
SELECT Quantity FROM inventory
WHEREItem='book';
...
UPDATE inventory SET Quantity=11
WHEREItem='book';
UNLOCK TABLES

這里,我們用一個 SELECT 語句取出初始數據,通過一些計算,用 UPDATE 語句將新值更新到表中。包含有 WRITE 關鍵字的 LOCK TABLE 語句可以保證在 UNLOCK TABLES 命令被執行之前,不會有其它的訪問來對 inventory 進行插入、更新或者刪除的操作。

6、使用外鍵

鎖定表的方法可以維護數據的完整性,但是它卻不能保證數據的關聯性。這個時候我們就可以使用外鍵。例如,外鍵可以保證每一條銷售記錄都指向某一個存在的客戶。在這里,外鍵可以把customerinfo 表中的CustomerID映射到salesinfo表中CustomerID,任何一條沒有合法CustomerID的記錄都不會被更新或插入到 salesinfo中。

CREATE TABLE customerinfo
(
CustomerID INT NOT NULL ,
PRIMARY KEY ( CustomerID )
) TYPE = INNODB;

CREATE TABLE salesinfo
(
SalesID INT NOT NULL,
CustomerID INT NOT NULL,
PRIMARY KEY(CustomerID, SalesID),
FOREIGN KEY (CustomerID) REFERENCES customerinfo
(CustomerID) ON DELETECASCADE
) TYPE = INNODB;

注意例子中的參數「ON DELETE CASCADE」。該參數保證當 customerinfo 表中的一條客戶記錄被刪除的時候,salesinfo 表中所有與該客戶相關的記錄也會被自動刪除。如果要在 MySQL 中使用外鍵,一定要記住在創建表的時候將表的類型定義為事務安全表 InnoDB類型。該類型不是 MySQL 表的默認類型。定義的方法是在 CREATE TABLE 語句中加上 TYPE=INNODB。如例中所示。

7、使用索引

索引是提高資料庫性能的常用方法,它可以令資料庫伺服器以比沒有索引快得多的速度檢索特定的行,尤其是在查詢語句當中包含有MAX(), MIN()和ORDERBY這些命令的時候,性能提高更為明顯。那該對哪些欄位建立索引呢?一般說來,索引應建立在那些將用於JOIN, WHERE判斷和ORDER BY排序的欄位上。盡量不要對資料庫中某個含有大量重復的值的欄位建立索引。對於一個ENUM類型的欄位來說,出現大量重復值是很有可能的情況,例如 customerinfo中的「province」.. 欄位,在這樣的欄位上建立索引將不會有什麼幫助;相反,還有可能降低資料庫的性能。我們在創建表的時候可以同時創建合適的索引,也可以使用ALTER TABLE或CREATE INDEX在以後創建索引。此外,MySQL

從版本3.23.23開始支持全文索引和搜索。全文索引在 MySQL 中是一個FULLTEXT類型索引,但僅能用於MyISAM 類型的表。對於一個大的資料庫,將數據裝載到一個沒有FULLTEXT索引的表中,然後再使用ALTER TABLE或CREATE INDEX創建索引,將是非常快的。但如果將數據裝載到一個已經有FULLTEXT索引的表中,執行過程將會非常慢。

8、優化的查詢語句

絕大多數情況下,使用索引可以提高查詢的速度,但如果SQL語句使用不恰當的話,索引將無法發揮它應有的作用。下面是應該注意的幾個方面。首先,最好是在相同類型的欄位間進行比較的操作。在MySQL 3.23版之前,這甚至是一個必須的條件。例如不能將一個建有索引的INT欄位和BIGINT欄位進行比較;但是作為特殊的情況,在CHAR類型的欄位和 VARCHAR類型欄位的欄位大小相同的時候,可以將它們進行比較。其次,在建有索引的欄位上盡量不要使用函數進行操作。

例如,在一個DATE類型的欄位上使用YEAE()函數時,將會使索引不能發揮應有的作用。所以,下面的兩個查詢雖然返回的結果一樣,但後者要比前者快得多。

SELECT * FROM order WHERE YEAR(OrderDate)<2001;

SELECT * FROM order WHERE OrderDate<"2001-01-01";

同樣的情形也會發生在對數值型欄位進行計算的時候:

SELECT * FROM inventory WHERE Amount/7<24;

SELECT * FROM inventory WHERE Amount<24*7;

上面的兩個查詢也是返回相同的結果,但後面的查詢將比前面的一個快很多。第三,在搜索字元型欄位時,我們有時會使用 LIKE 關鍵字和通配符,這種做法雖然簡單,但卻也是以犧牲系統性能為代價的。例如下面的查詢將會比較表中的每一條記錄。

SELECT * FROM books
WHERE name like "MySQL%"

但是如果換用下面的查詢,返回的結果一樣,但速度就要快上很多:

SELECT * FROM books
WHERE name>="MySQL"and name<"MySQM"

最後,應該注意避免在查詢中讓MySQL進行自動類型轉換,因為轉換過程也會使索引變得不起作用。

6、mysql資料庫怎麼優化,有幾方面的優化?

我列舉幾個我熟悉的,
1,存儲引擎,根據應用選擇合適的引擎
2,索引版
----這個就有很多文章了權,具體需要你自己去了解
3,sql語句優化,查詢條件的選擇之類
4,mysql自身系統配置,需要針對應用去定製
5,表的選擇,臨時表,或者分區表,也需要針對應用的情況去選擇使用

7、Mysql資料庫優化可以從哪幾個方面優化

1、選取最適用的欄位屬性

MySQL可以很好的支持大數據量的存取,但是一般說來,資料庫中的表越小,在它上面執行的查詢也就會越快。因此,在創建表的時候,為了獲得更好的性能,我們可以將表中欄位的寬度設得盡可能小。

2、使用連接(JOIN)來代替子查詢(Sub-Queries)

MySQL從4.1開始支持SQL的子查詢。這個技術可以使用SELECT語句來創建一個單列的查詢結果,然後把這個結果作為過濾條件用在另一個查詢中。例如,我們要將客戶基本信息表中沒有任何訂單的客戶刪除掉,就可以利用子查詢先從銷售信息表中將所有發出訂單的客戶ID取出來,然後將結果傳遞給主查詢。

3、使用聯合(UNION)來代替手動創建的臨時表

MySQL從4.0的版本開始支持union查詢,它可以把需要使用臨時表的兩條或更多的select查詢合並的一個查詢中。在客戶端的查詢會話結束的時候,臨時表會被自動刪除,從而保證資料庫整齊、高效。使用union來創建查詢的時候,我們只需要用UNION作為關鍵字把多個select語句連接起來就可以了,要注意的是所有select語句中的欄位數目要想同。下面的例子就演示了一個使用UNION的查詢。

4、事務

盡管我們可以使用子查詢(Sub-Queries)、連接(JOIN)和聯合(UNION)來創建各種各樣的查詢,但不是所有的資料庫操作都可以只用一條或少數幾條SQL語句就可以完成的。更多的時候是需要用到一系列的語句來完成某種工作。但是在這種情況下,當這個語句塊中的某一條語句運行出錯的時候,整個語句塊的操作就會變得不確定起來。設想一下,要把某個數據同時插入兩個相關聯的表中,可能會出現這樣的情況:第一個表中成功更新後,資料庫突然出現意外狀況,造成第二個表中的操作沒有完成,這樣,就會造成數據的不完整,甚至會破壞資料庫中的數據。要避免這種情況,就應該使用事務,它的作用是:要麼語句塊中每條語句都操作成功,要麼都失敗。換句話說,就是可以保持資料庫中數據的一致性和完整性。事物以BEGIN關鍵字開始,COMMIT關鍵字結束。在這之間的一條SQL操作失敗,那麼,ROLLBACK命令就可以把資料庫恢復到BEGIN開始之前的狀態。

5、鎖定表

盡管事務是維護資料庫完整性的一個非常好的方法,但卻因為它的獨占性,有時會影響資料庫的性能,尤其是在很大的應用系統中。由於在事務執行的過程中,資料庫將會被鎖定,因此其它的用戶請求只能暫時等待直到該事務結束。如果一個資料庫系統只有少數幾個用戶來使用,事務造成的影響不會成為一個太大的問題;但假設有成千上萬的用戶同時訪問一個資料庫系統,例如訪問一個電子商務網站,就會產生比較嚴重的響應延遲。其實,有些情況下我們可以通過鎖定表的方法來獲得更好的性能。

6、使用外鍵

鎖定表的方法可以維護數據的完整性,但是它卻不能保證數據的關聯性。這個時候我們就可以使用外鍵。

7、使用索引

索引是提高資料庫性能的常用方法,它可以令資料庫伺服器以比沒有索引快得多的速度檢索特定的行,尤其是在查詢語句當中包含有MAX(),MIN()和ORDERBY這些命令的時候,性能提高更為明顯。

希望可以幫到你,謝謝!

8、怎麼進行mysql資料庫優化?

主要從以下角度思考優化方向:1,Mysql配置優化主要對查詢緩存,mysql資料庫連接時長內,開啟慢查詢日誌容(開啟後還要分析sql)等方面進行優化2. Myslq語句優化3. Mysql索引優化主要是需要注意索引數量和索引失效情況,重復索引4. Mysql引擎優化innodb引擎注重於事務,能保證數據一致性myisam引擎可以進行全文檢索,但不是事務安全當初在黑馬程序員學過,還用實例進行優化學習。

9、MySQL伺服器如何進行調優??

第一種方法時替換有問題的硬體。對MySQL進程的設置進行調優。對查詢進行優化。
替換有問題的硬體通常是我們的第一考慮,主要原因是資料庫會佔用大量資源。不過這種解決方案也就僅限於此了。實際上,您通常可以讓中央處理器(CPU)或磁碟速度加倍,也可以讓內存增大4到8倍。
第二種方法是對MySQL伺服器(也稱為mysqld)進行調優。
對這個進程進行調優意味著適當地分配內存,並讓 mysqld 了解將會承受何種類型的負載。加快磁碟運行速度不如減少所需的磁碟訪問次數。類似地,確保 MySQL 進程正確操作就意味著它花費在服務查詢上的時間要多於花費在處理後台任務(如處理臨時磁碟表或打開和關閉文件)上的時間。對mysqld進行調優是本文的重點。
最好的方法是確保查詢已經進行了優化。這意味著對表應用了適當的索引,查詢是按照可以充分利用MySQL功能的方式來編寫的。盡管本文並沒有包含查詢調優方面的內容(很多著作中已經針對這個主題進行了探討),不過它會配置mysqld來報告可能需要進行調優的查詢。
雖然已經為這些任務指派了次序,但是仍然要注意硬體和mysqld的設置以利於適當地調優查詢。海外伺服器租用機器速度慢也就罷了,我曾經見過速度很快的機器在運行設計良好的查詢時由於負載過重而失敗,因為mysqld被大量繁忙的工作所佔用而不能服務查詢。
第三種方法是記錄慢速查詢
在一個SQL伺服器中,數據表都是保存在磁碟上的。索引為伺服器提供了一種在表中查找特定數據行的方法,而不用搜索整個表。當必須要搜索整個表時,就稱為表掃描。通常來說,您可能只希望獲得表中數據的一個子集,因此全表掃描會浪費大量的磁碟I/O,因此也就會浪費大量時間。當必須對數據進行連接時,這個問題就更加復雜了,因為必須要對連接兩端的多行數據進行比較。
當然,表掃描並不總是會帶來問題;有時讀取整個表反而會比從中挑選出一部分數據更加有效(伺服器進程中查詢規劃器用來作出這些決定)。如果索引的使 用效率很低,或者根本就不能使用索引,則會減慢查詢速度,而且隨著伺服器上的負載和表大小的增加,這個問題會變得更加顯著。執行時間超過給定時間范圍的查詢就稱為慢速查詢。
_深圳比特捷_

10、面試中常問:mysql資料庫做哪些優化也提高mysql性能

在開始演示之前,我們先介紹下兩個概念。


概念一,數據的可選擇性基數,也就是常說的cardinality值。


查詢優化器在生成各種執行計劃之前,得先從統計信息中取得相關數據,這樣才能估算每步操作所涉及到的記錄數,而這個相關數據就是cardinality。簡單來說,就是每個值在每個欄位中的唯一值分布狀態。


比如表t1有100行記錄,其中一列為f1。f1中唯一值的個數可以是100個,也可以是1個,當然也可以是1到100之間的任何一個數字。這里唯一值越的多少,就是這個列的可選擇基數。


那看到這里我們就明白了,為什麼要在基數高的欄位上建立索引,而基數低的的欄位建立索引反而沒有全表掃描來的快。當然這個只是一方面,至於更深入的探討就不在我這篇探討的范圍了。


概念二,關於HINT的使用。


這里我來說下HINT是什麼,在什麼時候用。


HINT簡單來說就是在某些特定的場景下人工協助MySQL優化器的工作,使她生成最優的執行計劃。一般來說,優化器的執行計劃都是最優化的,不過在某些特定場景下,執行計劃可能不是最優化。


比如:表t1經過大量的頻繁更新操作,(UPDATE,DELETE,INSERT),cardinality已經很不準確了,這時候剛好執行了一條SQL,那麼有可能這條SQL的執行計劃就不是最優的。為什麼說有可能呢?


來看下具體演示


譬如,以下兩條SQL,

A:

select * from t1 where f1 = 20;

B:

select * from t1 where f1 = 30;

如果f1的值剛好頻繁更新的值為30,並且沒有達到MySQL自動更新cardinality值的臨界值或者說用戶設置了手動更新又或者用戶減少了sample page等等,那麼對這兩條語句來說,可能不準確的就是B了。

這里順帶說下,MySQL提供了自動更新和手動更新表cardinality值的方法,因篇幅有限,需要的可以查閱手冊。

那回到正題上,MySQL 8.0 帶來了幾個HINT,我今天就舉個index_merge的例子。

示例表結構:

mysql> desc t1;+------------+--------------+------+-----+---------+----------------+| Field  | Type | Null | Key | Default | Extra  |+------------+--------------+------+-----+---------+----------------+| id | int(11)  | NO | PRI | NULL  | auto_increment || rank1  | int(11)  | YES  | MUL | NULL  |  || rank2  | int(11)  | YES  | MUL | NULL  |  || log_time | datetime | YES  | MUL | NULL  |  || prefix_uid | varchar(100) | YES  | | NULL  |  || desc1  | text | YES  | | NULL  |  || rank3  | int(11)  | YES  | MUL | NULL  |  |+------------+--------------+------+-----+---------+----------------+7 rows in set (0.00 sec)

表記錄數:

mysql> select count(*) from t1;+----------+| count(*) |+----------+|  32768 |+----------+1 row in set (0.01 sec)

這里我們兩條經典的SQL:

SQL C:

select * from t1 where rank1 = 1 or rank2 = 2 or rank3 = 2;

SQL D:

select * from t1 where rank1 =100  and rank2 =100  and rank3 =100;

表t1實際上在rank1,rank2,rank3三列上分別有一個二級索引。

那我們來看SQL C的查詢計劃。

顯然,沒有用到任何索引,掃描的行數為32034,cost為3243.65。

mysql> explain  format=json select * from t1  where rank1 =1 or rank2 = 2 or rank3 = 2G*************************** 1. row ***************************EXPLAIN: {  "query_block": {  "select_id": 1,  "cost_info": {  "query_cost": "3243.65"  },  "table": {  "table_name": "t1",  "access_type": "ALL",  "possible_keys": [  "idx_rank1",  "idx_rank2",  "idx_rank3"  ],  "rows_examined_per_scan": 32034,  "rows_proced_per_join": 115,  "filtered": "0.36",  "cost_info": {  "read_cost": "3232.07",  "eval_cost": "11.58",  "prefix_cost": "3243.65",  "data_read_per_join": "49K"  },  "used_columns": [  "id",  "rank1",  "rank2",  "log_time",  "prefix_uid",  "desc1",  "rank3"  ],  "attached_condition": "((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))"  }  }}1 row in set, 1 warning (0.00 sec)

我們加上hint給相同的查詢,再次看看查詢計劃。

這個時候用到了index_merge,union了三個列。掃描的行數為1103,cost為441.09,明顯比之前的快了好幾倍。

mysql> explain  format=json select /*+ index_merge(t1) */ * from t1  where rank1 =1 or rank2 = 2 or rank3 = 2G*************************** 1. row ***************************EXPLAIN: {  "query_block": {  "select_id": 1,  "cost_info": {  "query_cost": "441.09"  },  "table": {  "table_name": "t1",  "access_type": "index_merge",  "possible_keys": [  "idx_rank1",  "idx_rank2",  "idx_rank3"  ],  "key": "union(idx_rank1,idx_rank2,idx_rank3)",  "key_length": "5,5,5",  "rows_examined_per_scan": 1103,  "rows_proced_per_join": 1103,  "filtered": "100.00",  "cost_info": {  "read_cost": "330.79",  "eval_cost": "110.30",  "prefix_cost": "441.09",  "data_read_per_join": "473K"  },  "used_columns": [  "id",  "rank1",  "rank2",  "log_time",  "prefix_uid",  "desc1",  "rank3"  ],  "attached_condition": "((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))"  }  }}1 row in set, 1 warning (0.00 sec)

我們再看下SQL D的計劃:

不加HINT,

mysql> explain format=json select * from t1 where rank1 =100 and rank2 =100 and rank3 =100G*************************** 1. row ***************************EXPLAIN: {  "query_block": {  "select_id": 1,  "cost_info": {  "query_cost": "534.34"  },  "table": {  "table_name": "t1",  "access_type": "ref",  "possible_keys": [  "idx_rank1",  "idx_rank2",  "idx_rank3"  ],  "key": "idx_rank1",  "used_key_parts": [  "rank1"  ],  "key_length": "5",  "ref": [  "const"  ],  "rows_examined_per_scan": 555,  "rows_proced_per_join": 0,  "filtered": "0.07",  "cost_info": {  "read_cost": "478.84",  "eval_cost": "0.04",  "prefix_cost": "534.34",  "data_read_per_join": "176"  },  "used_columns": [  "id",  "rank1",  "rank2",  "log_time",  "prefix_uid",  "desc1",  "rank3"  ],  "attached_condition": "((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100))"  }  }}1 row in set, 1 warning (0.00 sec)

加了HINT,

mysql> explain format=json select /*+ index_merge(t1)*/ * from t1 where rank1 =100 and rank2 =100 and rank3 =100G*************************** 1. row ***************************EXPLAIN: {  "query_block": {  "select_id": 1,  "cost_info": {  "query_cost": "5.23"  },  "table": {  "table_name": "t1",  "access_type": "index_merge",  "possible_keys": [  "idx_rank1",  "idx_rank2",  "idx_rank3"  ],  "key": "intersect(idx_rank1,idx_rank2,idx_rank3)",  "key_length": "5,5,5",  "rows_examined_per_scan": 1,  "rows_proced_per_join": 1,  "filtered": "100.00",  "cost_info": {  "read_cost": "5.13",  "eval_cost": "0.10",  "prefix_cost": "5.23",  "data_read_per_join": "440"  },  "used_columns": [  "id",  "rank1",  "rank2",  "log_time",  "prefix_uid",  "desc1",  "rank3"  ],  "attached_condition": "((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100) and (`ytt`.`t1`.`rank1` = 100))"  }  }}1 row in set, 1 warning (0.00 sec)

對比下以上兩個,加了HINT的比不加HINT的cost小了100倍。

總結下,就是說表的cardinality值影響這張的查詢計劃,如果這個值沒有正常更新的話,就需要手工加HINT了。相信MySQL未來的版本會帶來更多的HINT。

與mysql伺服器優化相關的知識