資料庫查詢效率,小白速來

2021-10-02 03:02:34 字數 4021 閱讀 8767

為什麼有的專案,前段網頁顯示資料庫中的資料內容這麼緩慢?

原因

1、後台資料庫中的資料過多,沒做資料優化導致後台查詢資料慢

2、前端資料請求-解析-展示過程處理不當

3、網路原因

如何後台資料優化,提高資料庫查詢速度?

1、快取,在持久層或持久層之上做快取。

e.g. 使用ehcache快取,這個一般用於持久層的快取,提供持久層、業務層的快速快取,hibenate預設使用的二級快取就是ehcache。

2、資料庫表的大字段剝離。

e.g. 假如乙個表的字段數有100多個,學會拆分字段,保證單條記錄的資料量很小

3、恰當地使用索引;

e.g. 必要時建立多級索引,分析mysql的執行計畫,通過表資料統計等方式協助資料庫走正確的查詢方式,該走索引就走索引,該走全表掃瞄就走全表掃瞄;

4、表的拆分

e.g. 表分割槽和拆分,無論是業務邏輯上的拆分(如乙個月一張報表、分庫)還是無業務含義的分割槽(如根據id取模分割槽);

5、字段冗餘

e.g. 減少跨庫查詢和大表連線操作;,資料通過單個或多個job生成出來,減少實時查詢;

6、從磁碟上做文章

e.g. 資料存放的在磁碟的內、外磁軌上,資料獲取的效率都是不一樣的;

7、放棄關聯式資料庫的某些特性

e.g. 引入nosql資料庫;

換種思路存放資料,例如搜尋中的倒排表;

概念這些東西,看多了就生厭。接下來從資料庫查詢語句方面著手,來深度了解一下,什麼樣的查詢命令,效果會比較高。

對查詢進行優化,應盡可能避免全表掃瞄

首先應考慮在 where 及 order by 涉及的列上建立索引(假設我們有乙個table stu)

select * from stu   -----  全表查詢

更改為:

select * from stu where *** = '1' order by score; ---- 建立索引查詢

結論:(建立索引之後查詢速度會提高)

減少where字段值null判斷

select * from "tb_real_time_car" where pay_status = null (如何這樣做,就會導致引擎放棄使用索引而進行全表掃瞄)

更改為:

select * from "tb_real_time_car" where pay_status = 0(應該這樣去設定(也就是在沒有值時,我們在存資料庫時自動預設給個o值,而不是什麼都不寫):)

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

select * from "tb_real_time_car" where pay_status != null ;

//或者

select * from "tb_real_time_car" where pay_status <> null ; (這樣寫將導致引擎放棄使用索引而進行全表掃瞄。)

應盡量避免在 where 子句中使用 or 來連線條件

select * from "tb_real_time_car" where pay_status != null or enter_time = null;  (這樣將導致引擎放棄使用索引而進行全表掃瞄)

更改為:

select * from "tb_real_time_car" where pay_status != null union all 

select * from "tb_real_time_car" where enter_time = null; 

in 和 not in 也要慎用

select * from "tb_real_time_car" where rowed in [1,2,3,4]; 

//或者

select * from "tb_real_time_car" where rowed not in [1,2,3,4]; (這樣操作會導致全表掃瞄)

更改為:

select * from "tb_real_time_car" where rowed between 1 and 5; 

少使用模糊匹配 like

select * from "tb_real_time_car" where enter_time like '%2016-09-01%'

應盡量避免在 where 子句中對字段進行表示式操作

select * from "tb_real_time_car" where rowid/4 =100; (導致引擎放棄使用索引而進行全表掃瞄)

更改為:

select * from "tb_real_time_car" where rowid =4*100;

很多時候用 exists 代替 in 是乙個好的選擇

select * from "tb_real_time_car" where rowed (select rowed from "tb_real");

更改為:

select * from "tb_real_time_car" where exists (select rowed from "tb_real" where rowed = tb_real.rowid);

關於索引的技巧

1、並不是所有索引對查詢都有效

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

2、索引並不是越多越好

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

3、應盡可能的避免更新 clustered 索引資料列

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

4、盡量使用數字型字段

若只含數值資訊的字段盡量不要設計為字元型,這會降低查詢和連線的效能,並會增加儲存開銷。這是因為引擎在處理查詢和連線時會逐個比較字串中每乙個字元,而對於數字型而言只需要比較一次就夠了。

建立資料庫時應注意:

1、盡可能的使用 varchar/nvarchar 代替 char/nchar

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

2、用表變數來代替臨時表。

#####1. 如果表變數包含大量資料,請注意索引非常有限(只有主鍵索引)。

#####2. 在新建臨時表時,如果一次性插入資料量很大,那麼可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果資料量不大,為了緩和系統表的資源,應先create table,然後insert。

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

本博總結於:

資料庫查詢提公升查詢效率

在乙個千萬級別的資料庫查詢中,提公升查詢效率方法 對查詢優化,要盡量避免全表掃瞄,首先考慮在where和orderby涉及的列上建索引 應盡量避免在where字句中對null值進行判斷,否則導致引擎放棄索引而進行全表掃瞄,如 select id from t where num is null,可以...

查詢資料庫效率問題

asp mssql,分頁部分。一種是使用記錄集實現分頁 set rs server.createobject adodb.recordset rs.open select from table conn,1,1 rs.pagesize 10 rs.absolutepage 1 另一種是直接使用sql...

資料庫優化查詢效率

1 儲存引擎選擇 如果資料表需要事務處理,應該考慮使用 innodb,因為它完全符合 acid 特性。如果不需要事務處理,使用預設儲存引擎 myisam 是比較明智的 2 分表分庫,主從。3 對查詢進行優化,要盡量避免全表掃瞄,首先應考慮在 where 及 order by 涉及的列上建立索 引 4...