當前位置:首頁 » 編程語言 » sqlserversql語句優化
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sqlserversql語句優化

發布時間: 2022-08-06 04:42:56

sql 語句優化問題

事實上,這樣的擔心是不必要的。SQL
SERVER中有一個「查詢分析優化器」,它可以計算出WHERE子句中的搜索條件並確定哪個索引能縮小表掃描的搜索空間,也就是說,它能實現自動優化。
雖然查詢優化器可以根據WHERE子句自動的進行查詢優化,但仍然有必要了解一下「查詢優化器」的工作原理,如非這樣,有時查詢優化器就會不按照您的本意進行快速查詢。
在查詢分析階段,查詢優化器查看查詢的每個階段並決定限制需要掃描的數據量是否有用。如果一個階段可以被用作一個掃描參數(SARG),那麼就稱之為可優化的,並且可以利用索引快速獲得所需數據。
SARG的定義:用於限制搜索的一個操作,因為它通常是指一個特定的匹配,一個值得范圍內的匹配或者兩個以上條件的AND連接。形式如下:
列名
操作符
<常數

變數>或<常數

變數>
操作符列名
列名可以出現在操作符的一邊,而常數或變數出現在操作符的另一邊。如:
Name=』張三』價格>5000
5000<價格
Name=』張三』
and
價格>5000
如果一個表達式不能滿足SARG的形式,那它就無法限制搜索的范圍了,也就是SQL
SERVER必須對每一行都判斷它是否滿足WHERE子句中的所有條件。所以一個索引對於不滿足SARG形式的表達式來說是無用的。
常見的SARG判別經驗:
Like語句是否屬於SARG取決於所使用的通配符的類型
如:name
like
『張%』,這就屬於SARG
而:name
like
『%張』,就不屬於SARG。
原因是通配符%在字元串的開通使得索引無法使用。
or
會引起全表掃描。
Name
=
』張三』
AND
價格>5000,符合SARG,
Name
=
』張三』
OR
價格>5000,不符合SARG。
原因是使用or會引起全表掃描。
非操作符、函數引起的不滿足SARG形式的語句。
不滿足SARG形式的語句最典型的情況就是包括非操作符的語句,如:NOT、!=、<>、!<、!>、NOT
EXISTS、NOT
IN、NOT
LIKE等,另外還有函數。下面就是幾個不滿足SARG形式的例子:
ABS(價格)<5000
Name
like
『%三』
有些表達式,如:WHERE
價格*2>5000
SQL
SERVER也會認為是SARG,SQL
SERVER會將此式轉化為:價格>5000/2
但不推薦這樣使用,因為有時SQL
SERVER不能保證這種轉化與原始表達式是完全等價的。

㈡ 怎麼樣寫SQL語句可以提高資料庫的執行速度應該注意那些

這個范圍太大了,一下子是很難說清楚的,如果用sql
server
的話,可以使用它自帶的優化器來優化,然後看看它給你的建議去優化。要注意規范化編程。而且要抓住一個原則來寫,就是進可能縮小查詢出來的結果集,哪怕多次查詢都沒所謂,要一步一步把大數據量縮小。很多隻是還是得在時間中優化。SET
STATISTICS
TIME
ON;SQL
語句SET
STATISTICS
TIME
OFF;這個是sqlserver
,可以測出執行時間。編寫的時候要時刻想著:縮小結果集、減少連接次數和表數。大數據量不要用update,可以用臨時表作為過度來實現update操作。

㈢ 如何做SqlServer 數據查詢優化!

一、建立索引
二、建立存儲過程
三、只查詢您所需要的數據,不要把所有數據都查詢出來,防止數據冗餘。
四、對於大量及海量數據一般還要建立分區

㈣ 如何解決SQL查詢速度太慢

1. 執行計劃中明明有使用到索引,為什麼執行還是這么慢?

2. 執行計劃中顯示掃描行數為 644,為什麼 slow log 中顯示 100 多萬行?
a. 我們先看執行計劃,選擇的索引 「INDX_BIOM_ELOCK_TASK3(TASK_ID)」。結合 sql 來看,因為有 "ORDER BY TASK_ID DESC" 子句,排序通常很慢,如果使用了文件排序性能會更差,優化器選擇這個索引避免了排序。
那為什麼不選 possible_keys:INDX_BIOM_ELOCK_TASK 呢?原因也很簡單,TASK_DATE 欄位區分度太低了,走這個索引需要掃描的行數很大,而且還要進行額外的排序,優化器綜合判斷代價更大,所以就不選這個索引了。不過如果我們強制選擇這個索引(用 force index 語法),會看到 SQL 執行速度更快少於 10s,那是因為優化器基於代價的原則並不等價於執行速度的快慢;
b. 再看執行計劃中的 type:index,"index" 代表 「全索引掃描」,其實和全表掃描差不多,只是掃描的時候是按照索引次序進行而不是行,主要優點就是避免了排序,但是開銷仍然非常大。
Extra:Using where 也意味著掃描完索引後還需要回表進行篩選。一般來說,得保證 type 至少達到 range 級別,最好能達到 ref。
在第 2 點中提到的「慢日誌記錄Rows_examined: 1161559,看起來是全表掃描」,這里更正為「全索引掃描」,掃描行數確實等於表的行數;
c. 關於執行計劃中:「rows:644」,其實這個只是估算值,並不準確,我們分析慢 SQL 時判斷准確的掃描行數應該以 slow log 中的 Rows_examined 為准。
4. 優化建議:添加組合索引 IDX_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID)

優化過程:
TASK_DATE 欄位存在索引,但是選擇度很低,優化器不會走這個索引,建議後續可以刪除這個索引:
select count(*),count(distinct TASK_DATE) from T_BIOMA_ELOCK_TASK;+------------+---------------------------+| count(*) | count(distinct TASK_DATE) |+------------+---------------------------+| 1161559 | 223 |+------------+---------------------------+

在這個 sql 中 REL_DEVID 欄位從命名上看選擇度較高,通過下面 sql 來檢驗確實如此:
select count(*),count(distinct REL_DEVID) from T_BIOMA_ELOCK_TASK;+----------+---------------------------+| count(*) | count(distinct REL_DEVID) |+----------+---------------------------+| 1161559 | 62235 |+----------+---------------------------+

由於有排序,所以得把 task_id 也加入到新建的索引中,REL_DEVID,task_id 組合選擇度 100%:
select count(*),count(distinct REL_DEVID,task_id) from T_BIOMA_ELOCK_TASK;+----------+-----------------------------------+| count(*) | count(distinct REL_DEVID,task_id) |+----------+-----------------------------------+| 1161559 | 1161559 |+----------+-----------------------------------+

在測試環境添加 REL_DEVID,TASK_ID 組合索引,測試 sql 性能:alter table T_BIOMA_ELOCK_TASK add index idx_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID);
添加索引後執行計劃:
這里還要注意一點「隱式轉換」:REL_DEVID 欄位數據類型為 varchar,需要在 sql 中加引號:AND T.REL_DEVID = 000000025xxx >> AND T.REL_DEVID = '000000025xxx'

執行時間從 10s+ 降到 毫秒級別:
1 row in set (0.00 sec)
結論
一個典型的 order by 查詢的優化,添加更合適的索引可以避免性能問題:執行計劃使用索引並不意味著就能執行快。

㈤ SQL Server資料庫的高性能優化經驗總結

本文主要向大家介紹的是正確優化SQL
Server資料庫的經驗總結,其中包括在對其進行優化的實際操作中值得大家注意的地方描述,以及對SQL語句進行優化的最基本原則,以下就是文章的主要內容描述。
優化資料庫的注意事項:
1、關鍵欄位建立索引。
2、使用存儲過程,它使SQL變得更加靈活和高效。
3、備份資料庫和清除垃圾數據。
4、SQL語句語法的優化。(可以用Sybase的SQL
Expert,可惜我沒找到unexpired的序列號)
5、清理刪除日誌。
SQL語句優化的基本原則:
1、使用索引來更快地遍歷表。
預設情況下建立的索引是非群集索引,但有時它並不是最佳的。在非群集索引下,數據在物理上隨機存放在數據頁上。合理的索引設計要建立在對各種查詢的分析和預測上。
一般來說:
①.有大量重復值、且經常有范圍查詢(between,
>,<
,>=,<
=)和order
by、group
by發生的列,可考慮建立群集索引
②.經常同時存取多列,且每列都含有重復值可考慮建立組合索引;
③.組合索引要盡量使關鍵查詢形成索引覆蓋,其前導列一定是使用最頻繁的列。
2、IS
NULL

IS
NOT
NULL
不能用null作索引,任何包含null值的列都將不會被包含在索引中。即使索引有多列這樣的情況下,只要這些列中有一列含有null,該列就會從索引中排除。也就是說如果某列存在空值,即使對該列建索引也不會提高性能。任何在where子句中使用is
null或is
not
null的語句優化器是不允許使用索引的。
3、IN和EXISTS
EXISTS要遠比IN的效率高。裡面關繫到full
table
scan和range
scan。幾乎將所有的IN操作符子查詢改寫為使用EXISTS的子查詢。
4、在海量查詢時盡量少用格式轉換。
5、當在SQL
SERVER
2000中
如果存儲過程只有一個參數,並且是OUTPUT類型的,必須在調用這個存儲過程的時候給這個參數一個初始的值,否則會出現調用錯誤。
6、ORDER
BY和GROPU
BY
使用ORDER
BY和GROUP
BY短語,任何一種索引都有助於SELECT的性能提高。注意如果索引列裡面有NULL值,Optimizer將無法優化。
7、任何對列的操作都將導致表掃描,它包括SQL
Server資料庫函數、計算表達式等等,查詢時要盡可能將操作移至等號右邊。
8、IN、OR子句常會使用工作表,使索引失效。如果不產生大量重復值,可以考慮把子句拆開。拆開的子句中應該包含索引。
9、SET
SHOWPLAN_ALL>10、謹慎使用游標
在某些必須使用游標的場合,可考慮將符合條件的數據行轉入臨時表中,再對臨時表定義游標進行操作,這樣可使性能得到明顯提高。
注釋:所謂的優化就是WHERE子句利用了索引,不可優化即發生了表掃描或額外開銷。經驗顯示,SQL
Server資料庫性能的最大改進得益於邏輯的資料庫設計、索引設計和查詢設計方面。反過來說,最大的性能問題常常是由其中這些相同方面中的不足引起的。
其實SQL優化的實質就是在結果正確的前提下,用優化器可以識別的語句,充份利用索引,減少表掃描的I/O次數,盡量避免表搜索的發生。其實SQL的性能優化是一個復雜的過程,上述這些只是在應用層次的一種體現,深入研究還會涉及SQL
Server資料庫層的資源配置、網路層的流量控制以及操作系統層的總體設計。

㈥ 求優化sqlserver語句,使它查詢效率提高。(要求:分組查詢每組最新的一條數據,數據量非常大,幾十萬)

關於題主的SQL語句提高效率的問題,請留意一下幾點

1) 輸出的欄位列表裡只有來自表「dbo.tunnel_online_monitoring 」里的欄位信息,沒有任何來欄位取自表「dbo.Threshold_ElectronicPool」,而且語句也沒為這兩張表指定連接條件,因此將表「dbo.Threshold_ElectronicPool」引入語句中就沒有任何必要,加入該表只會大大增加系統開銷,而無得益,應予以剔除;

2)row_number()函數的系統開銷是比較大的,能不用盡量別用它。

如果dbo.tunnel_online_monitoring.Id是唯一的,可以不使用row_number()函數,建議語句修改如下:

selectId,CreationDate,LastUpdate,tunnel_name,
SDMC,DT,DZSC1,DZSC2,DZSC3from
tunnel_online_monitoringwhereidin(
selectmax(a.id)fromdbo.tunnel_online_monitoringa,
(selecttunnel_name,max(CreationDate)asCreationDatefrom
dbo.tunnel_online_monitoringgroupbytunnel_name)b
wherea.tunnel_name=b.tunnel_nameanda.CreationDate
=b.CreationDategroupbyb.tunnel_name);

如果dbo.tunnel_online_monitoring.Id是自增ID,那麼可以根據ID的大小來判定那條記錄是最新的,這樣就不需要比對時間欄位的先後了,語句可簡化如下:

selectId,CreationDate,LastUpdate,tunnel_name,
SDMC,DT,DZSC1,DZSC2,DZSC3from
tunnel_online_monitoringwhereidin(
selectmax(id)fromdbo.tunnel_online_monitoring
groupbytunnel_name);

如果dbo.tunnel_online_monitoring.Id不是唯一的,那就還是得利用回row_number()函數了。

㈦ SQL語句 優化問題,提高性能

唉。。。說的千奇百怪什麼都有,真是。。。。

下面,說說我的看法:
首先,like '%asdasd%'會造成表掃描。
其次,like 'asdasd%'可能無法滿足樓主的要求
再次,like 並不是只有查不到的時候才遍歷全表,是每次都要遍歷。

給樓主兩個建議方案,第一就是給 關鍵字 欄位建索引
例如 select * from table1 where id like '%qweqwe%'
此時如果id有索引,或者是主鍵,那麼就應該不會構成表掃描。但是有時候也有例外,有時候一樣的腳本,換換格式,效率也就不一樣,相信是優化器的作用。

第二方案,查詢沒有數據的時候慢,那麼樓主試試不要查出每條數據,用count(*)先查一下試試,如果結果為0,就不用查了。
不過不是很建議用第二方案,除非迫不得已。

還有,樓主可以用查詢分析器分析一下腳本的效率,看看什麼地方構成表掃描,改善一下即可

㈧ SQL優化問題

問題1,2,3,其實效率是一樣高的,因為現在的sqlserver,oracle,都有sql語句優化分析器,語句不同的寫法,到最後編譯之後,其實是一樣的。

4,如果對欄位like,而且是%key%這樣的方式,索引就不起作用了,所以加上索引也沒用。

㈨ 怎樣進行sql資料庫的優化

1、資料庫空間是個概述,在sqlserver里,使用語句 exec sp_spaceused 'TableName' 這個語句來查。

㈩ 怎麼用SQL語句去優化資料庫是SQLserver2005

通常情況下,即在資料庫的數據量,伺服器硬體都在承受范圍內,進行的是:
1.語句調優,包括創建索引,優化語句的實現方式使執行計劃更流暢
2.表結構變更,即在語句級別的調優沒有辦法滿足性能要求的時候不得不採用的措施.包括表的拆分,橫向拆分,縱向拆分等
還有其他的一些比較大的改動,包括伺服器遷移,讀寫分離,分布式規劃等等