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

sql語句優化程序

發布時間: 2022-07-12 05:44:41

sql語句的幾種優化方法

1、盡可能建立索引,包括條件列,連接列,外鍵列等。

2、盡可能讓where中的列順序與復合索引的列順序一致。

3、盡可能不要select *,而只列出自己需要的欄位列表。

4、盡可能減少子查詢的層數。

5、盡可能在子查詢中進行數據篩選 。

⑵ sql語句怎麼優化

dd_order 表 欄位 create_time 聚集索引,其他欄位也可建索引,使用exists效率比in 效率高。
你執行如下語句,看是否提高的效率。

select count(distinct user_id)
from dd_order a where buy_channel in (1,2)
and status = 3
and create_time>='20150825'
and create_time<='20150825'
and not exists(
select user_id from dd_order b
where
a.user_id=b.user_id
and buy_channel in (1,2)
and status = 3
and
create_time< '20150825' )

⑶ sql語句性能如何優化

如何加快查詢速度?
1、升級硬體
2、根據查詢條件,建立索引,優化索引、優化訪問方式,限制結果集的數據量。
3、擴大伺服器的內存
4、增加伺服器CPU個數
5、對於大的資料庫不要設置資料庫自動增長,它會降低伺服器的性能
6、在查詢Select語句中用Where字句限制返回的行數,避免表掃描,如果返回不必要的數據,浪費了伺服器的I/O資源,加重了網路的負擔降低性能。如果表很大,在表掃描的期間將表鎖住,禁止其他的聯接訪問表,後果嚴重。
7、查詢時不要返回不需要的行、列
8、用select top 100 / 10 Percent 來限制用戶返回的行數或者SET ROWCOUNT來限制操作的行
9、在IN後面值的列表中,將出現最頻繁的值放在最前面,出現得最少的放在最後面,減少判斷的次數
10、一般在GROUP BY 個HAVING字句之前就能剔除多餘的行,所以盡量不要用它們來做剔除行的工作。他們的執行順序應該如下最優:
select的Where字句選擇所有合適的行,Group By用來分組個統計行,Having字句用來剔除多餘的分組。這樣Group By 個Having的開銷小,查詢快.對於大的數據行進行分組和Having十分消耗資源。如果Group BY的目的不包括計算,只是分組,那麼用Distinct更快
11、一次更新多條記錄比分多次更新每次一條快,就是說批處理好

⑷ Sql語句優化

1.查看鏈接查詢部分是不是鍵和索引
2.檢查d.area_id是不是有索引
3.檢查a.alloc_date是不是有索引
4.將Or鏈接的條件改成union all的方式來查詢
5.(可能是關鍵)to_char(a.alloc_date,'yyyymm')>='200805' 這個函數方式的,改為直接方式的a.alloc_date >= date'2008-05-01' 避免全表掃描
6.(也可能是關鍵)檢查類型一致性,area_id in d.area_id in (17000124,17000125,17000126,17000127) 這個就要求area_id 一定是數值的,否則很大幾率對area_id做轉換函數從而全表掃描的。如果是字元串的in後面的每一項就應該加上單引號。
7.經in語法改成or語法
8.如果還不行的話,根據表的大小情況做成嵌套查詢,以便強制條件的應用順序,以避免先連接再篩選的情況發生。

以上只是建議,具體的如果我猜的不錯的話用的是oracle,那麼在PL/SQL裡面將查詢部分摘出來,執行後按F5就可以看到解釋計劃窗口了,看看瓶頸在什麼地方

⑸ SQL語句優化

select id from table
WHERE
( a=9 AND b=7 )
OR
( a=0 AND b=1 )
AND c > 0

這個語句就一層沒有太大的優化
sql語句被解析的時候where條件是從後往前篩選的
所以你可以根據篩選掉的數據量 把where條件位置變換一下
無比將能篩選掉最多不符的數據放到最後
再就是為了減少數據的篩選量c>0最好改成c>=1

⑹ SQL 語句優化,該怎麼處理

(1)選擇最有效率的表名順序(只在基於規則的優化器中有效):
ORACLE的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫
在最後的表(基礎表 driving table)將被最先處理,在FROM子句中包含多個表的
情況下,你必須選擇記錄條數最少的表作為基礎表。如果有3個以上的表連接查詢
, 那就需要選擇交叉表(intersection table)作為基礎表, 交叉表是指那個被其
他表所引用的表.
(2) WHERE子句中的連接順序.:
ORACLE採用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必
須寫在其他WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE
子句的末尾.
(3) SELECT子句中避免使用『 * 『:
ORACLE在解析的過程中, 會將'*' 依次轉換成所有的列名, 這個工作是通過
查詢數據字典完成的, 這意味著將耗費更多的時間
(4)減少訪問資料庫的次數:
ORACLE在內部執行了許多工作: 解析SQL語句, 估算索引的利用率, 綁定變
量 , 讀數據塊等;
(5)在SQL*Plus , SQL*Forms和Pro*C中重新設置ARRAYSIZE參數, 可以增加
每次資料庫訪問的檢索數據量 ,建議值為200
(6)使用DECODE函數來減少處理時間:
使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表.
(7)整合簡單,無關聯的資料庫訪問:
如果你有幾個簡單的資料庫查詢語句,你可以把它們整合到一個查詢中(即使
它們之間沒有關系)
(8)刪除重復記錄:
最高效的刪除重復記錄方法 ( 因為使用了ROWID)例子:
DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID)
FROM EMP X WHERE X.EMP_NO = E.EMP_NO);
(9)用TRUNCATE替代DELETE:
當刪除表中的記錄時,在通常情況下, 回滾段(rollback segments ) 用來存
放可以被恢復的信息. 如果你沒有COMMIT事務,ORACLE會將數據恢復到刪除之前
的狀態(准確地說是恢復到執行刪除命令之前的狀況) 而當運用TRUNCATE時, 回
滾段不再存放任何可被恢復的信息.當命令運行後,數據不能被恢復.因此很少的
資源被調用,執行時間也會很短. (譯者按: TRUNCATE只在刪除全表適
用,TRUNCATE是DDL不是DML)
(10)盡量多使用COMMIT:
只要有可能,在程序中盡量多使用COMMIT, 這樣程序的性能得到提高,需求也
會因為COMMIT所釋放的資源而減少:
COMMIT所釋放的資源:
a. 回滾段上用於恢復數據的信息.
b. 被程序語句獲得的鎖
c. redo log buffer 中的空間
d. ORACLE為管理上述3種資源中的內部花費
(11)用Where子句替換HAVING子句:
避免使用HAVING子句, HAVING 只會在檢索出所有記錄之後才對結果集進行
過濾. 這個處理需要排序,總計等操作. 如果能通過WHERE子句限制記錄的數目,
那就能減少這方面的開銷. (非oracle中)on、where、having這三個都可以加條
件的子句中,on是最先執行,where次之,having最後,因為on是先把不符合條
件的記錄過濾後才進行統計,它就可以減少中間運算要處理的數據,按理說應該
速度是最快的,where也應該比having快點的,因為它過濾數據後才進行sum,在
兩個表聯接時才用on的,所以在一個表的時候,就剩下where跟having比較了。
在這單表查詢統計的情況下,如果要過濾的條件沒有涉及到要計算欄位,那它們
的結果是一樣的,只是where可以使用rushmore技術,而having就不能,在速度
上後者要慢如果要涉及到計算的欄位,就表示在沒計算之前,這個欄位的值是不
確定的,根據上篇寫的工作流程,where的作用時間是在計算之前就完成的,而
having就是在計算後才起作用的,所以在這種情況下,兩者的結果會不同。在多
表聯接查詢時,on比where更早起作用。系統首先根據各個表之間的聯接條件,
把多個表合成一個臨時表後,再由where進行過濾,然後再計算,計算完後再由
having進行過濾。由此可見,要想過濾條件起到正確的作用,首先要明白這個條
件應該在什麼時候起作用,然後再決定放在那裡
(12)減少對表的查詢:
在含有子查詢的SQL語句中,要特別注意減少對表的查詢.例子:
SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT
TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)
(13)通過內部函數提高SQL效率.:
復雜的SQL往往犧牲了執行效率. 能夠掌握上面的運用函數解決問題的方法
在實際工作中是非常有意義的
(14)使用表的別名(Alias):
當在SQL語句中連接多個表時, 請使用表的別名並把別名前綴於每個Column
上.這樣一來,就可以減少解析的時間並減少那些由Column歧義引起的語法錯誤.
(15)用EXISTS替代IN、用NOT EXISTS替代NOT IN:
在許多基於基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯
接.在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的效率. 在子查
詢中,NOT IN子句將執行一個內部的排序和合並. 無論在哪種情況下,NOT IN都是
最低效的 (因為它對子查詢中的表執行了一個全表遍歷). 為了避免使用NOT IN
,我們可以把它改寫成外連接(Outer Joins)或NOT EXISTS.
例子:
(高效)SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND EXISTS (SELECT
『X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = 『MELB')
(低效)SELECT * FROM EMP (基礎表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT
DEPTNO FROM DEPT WHERE LOC = 『MELB')
(16)識別'低效執行'的SQL語句:
雖然目前各種關於SQL優化的圖形化工具層出不窮,但是寫出自己的SQL工具
來解決問題始終是一個最好的方法:
SELECT EXECUTIONS , DISK_READS, BUFFER_GETS, ROUND((BUFFER_GETS-
DISK_READS)/BUFFER_GETS,2) Hit_radio, ROUND(DISK_READS/EXECUTIONS,2)
Reads_per_run,
SQL_TEXT FROM V$SQLAREA WHERE EXECUTIONS>0 AND BUFFER_GETS > 0 AND
(BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8 ORDER BY 4 DESC;
(17)用索引提高效率:
索引是表的一個概念部分,用來提高檢索數據的效率,ORACLE使用了一個復
雜的自平衡B-tree結構. 通常,通過索引查詢數據比全表掃描要快. 當ORACLE找
出執行查詢和Update語句的最佳路徑時, ORACLE優化器將使用索引. 同樣在聯結
多個表時使用索引也可以提高效率. 另一個使用索引的好處是,它提供了主鍵
(primary key)的唯一性驗證.。那些LONG或LONG RAW數據類型, 你可以索引幾乎
所有的列. 通常, 在大型表中使用索引特別有效. 當然,你也會發現, 在掃描小
表時,使用索引同樣能提高效率. 雖然使用索引能得到查詢效率的提高,但是我們
也必須注意到它的代價. 索引需要空間來存儲,也需要定期維護, 每當有記錄在
表中增減或索引列被修改時, 索引本身也會被修改. 這意味著每條記錄的INSERT
, DELETE , UPDATE將為此多付出4 , 5 次的磁碟I/O . 因為索引需要額外的存
儲空間和處理,那些不必要的索引反而會使查詢反應時間變慢.。定期的重構索引
是有必要的.:
ALTER INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
(18)用EXISTS替換DISTINCT:
當提交一個包含一對多表信息(比如部門表和雇員表)的查詢時,避免在
SELECT子句中使用DISTINCT. 一般可以考慮用EXIST替換, EXISTS 使查詢更為迅
速,因為RDBMS核心模塊將在子查詢的條件一旦滿足後,立刻返回結果. 例子:
(低效): SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E
WHERE D.DEPT_NO = E.DEPT_NO (高效): SELECT DEPT_NO,DEPT_NAME FROM DEPT
D WHERE EXISTS ( SELECT 『X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
(19) sql語句用大寫的;因為oracle總是先解析sql語句,把小寫的字母轉換成大寫的再執行
(20)在java代碼中盡量少用連接符「+」連接字元串!

⑺ 如何優化SQL語句

一、問題的提出
在應用系統開發初期,由於開發資料庫數據比較少,對於查詢SQL語句,復雜視圖的的編寫等體會不出SQL語句各種寫法的性能優劣,但是如果將應用系統提交實際應用後,隨著資料庫中數據的增加,系統的響應速度就成為目前系統需要解決的最主要的問題之一。系統優化中一個很重要的方面就是SQL語句的優化。對於海量數據,劣質SQL語句和優質SQL語句之間的速度差別可以達到上百倍,可見對於一個系統不是簡單地能實現其功能就可,而是要寫出高質量的SQL語句,提高系統的可用性。
在多數情況下,Oracle使用索引來更快地遍歷表,優化器主要根據定義的索引來提高性能。但是,如果在SQL語句的where子句中寫的SQL代碼不合理,就會造成優化器刪去索引而使用全表掃描,一般就這種SQL語句就是所謂的劣質SQL語句。在編寫SQL語句時我們應清楚優化器根據何種原則來刪除索引,這有助於寫出高性能的SQL語句。
二、SQL語句編寫注意問題
下面就某些SQL語句的where子句編寫中需要注意的問題作詳細介紹。在這些where子句中,即使某些列存在索引,但是由於編寫了劣質的SQL,系統在運行該SQL語句時也不能使用該索引,而同樣使用全表掃描,這就造成了響應速度的極大降低。
1.
IS
NULL

IS
NOT
NULL
不能用null作索引,任何包含null值的列都將不會被包含在索引中。即使索引有多列這樣的情況下,只要這些列中有一列含有null,該列就會從索引中排除。也就是說如果某列存在空值,即使對該列建索引也不會提高性能。
任何在where子句中使用is
null或is
not
null的語句優化器是不允許使用索引的。
2.
聯接列
對於有聯接的列,即使最後的聯接值為一個靜態值,優化器是不會使用索引的。我們一起來看一個例子,假定有一個職工表(employee),對於一個職工的姓和名分成兩列存放(FIRST_NAME和LAST_NAME),現在要查詢一個叫比爾.柯林頓(Bill
Cliton)的職工。
下面是一個採用聯接查詢的SQL語句,
select
*
from
employss
where
first_name||''||last_name
='Beill
Cliton';
上面這條語句完全可以查詢出是否有Bill
Cliton這個員工,但是這里需要注意,系統優化器對基於last_name創建的索引沒有使用。
當採用下面這種SQL語句的編寫,Oracle系統就可以採用基於last_name創建的索引。
***
where
first_name
='Beill'
and
last_name
='Cliton';
.
帶通配符(%)的like語句
同樣以上面的例子來看這種情況。目前的需求是這樣的,要求在職工表中查詢名字中包含cliton的人。可以採用如下的查詢SQL語句:
select
*
from
employee
where
last_name
like
'%cliton%';
這里由於通配符(%)在搜尋詞首出現,所以Oracle系統不使用last_name的索引。在很多情況下可能無法避免這種情況,但是一定要心中有底,通配符如此使用會降低查詢速度。然而當通配符出現在字元串其他位置時,優化器就能利用索引。在下面的查詢中索引得到了使用:
select
*
from
employee
where
last_name
like
'c%';
4.
Order
by語句
ORDER
BY語句決定了Oracle如何將返回的查詢結果排序。Order
by語句對要排序的列沒有什麼特別的限制,也可以將函數加入列中(象聯接或者附加等)。任何在Order
by語句的非索引項或者有計算表達式都將降低查詢速度。
仔細檢查order
by語句以找出非索引項或者表達式,它們會降低性能。解決這個問題的辦法就是重寫order
by語句以使用索引,也可以為所使用的列建立另外一個索引,同時應絕對避免在order
by子句中使用表達式。
5.
NOT
我們在查詢時經常在where子句使用一些邏輯表達式,如大於、小於、等於以及不等於等等,也可以使用and(與)、or(或)以及not(非)。NOT可用來對任何邏輯運算符號取反。下面是一個NOT子句的例子:
...
where
not
(status
='VALID')
如果要使用NOT,則應在取反的短語前面加上括弧,並在短語前面加上NOT運算符。NOT運算符包含在另外一個邏輯運算符中,這就是不等於(<>)運算符。換句話說,即使不在查詢where子句中顯式地加入NOT詞,NOT仍在運算符中,見下例:
...
where
status
<>'INVALID';
對這個查詢,可以改寫為不使用NOT:
select
*
from
employee
where
salary<3000
or
salary>3000;
雖然這兩種查詢的結果一樣,但是第二種查詢方案會比第一種查詢方案更快些。第二種查詢允許Oracle對salary列使用索引,而第一種查詢則不能使用索引。
雖然這兩種查詢的結果一樣,但是第二種查詢方案會比第一種查詢方案更快些。第二種查詢允許Oracle對salary列使用索引,而第一種查詢則不能使用索引。

⑻ 如何進行SQL性能優化

這里分享下mysql優化的幾種方法。

1、首先在打開的軟體中,需要分別為每一個表創建 InnoDB FILE的文件。

⑼ 開發中,SQL語句優化有哪些方法

看你資料庫類型和框架是否支持。

一般開發中遇到慢SQL存在3個問題(索引健全的情況下)。

  1. 數據量多導致總行數慢,因為數據在不歸檔、遷移、轉總賬的情況下會不斷積壓。許可權越高看見的數據量就越大,數據量越大總行數就越高。一般框架是以分頁的SQL為基礎計算總行數的。這樣就會導致掃描行數高物理讀高查詢速度慢。優化方案就是總行數進行狀態歸檔,以歸檔+實時的方式展現出來

  2. 連表超過多,部分數據表是單獨的,但是不同部門的數據又有關聯性,領導要看全生命周期或者流程數據的情況下必須多表相連。這樣由於N個明細表導致笛卡兒積先不說,邏輯復雜連表多會消耗CPU,哪怕你查詢能500毫秒內顯示但是如果多人同時查就讓CPU超100%甚至做成鎖等待等堵塞。這個情況就是要用類似「雲計算」的分布式計算。通過觸發器、存儲過程等規定時間內吧業務表數據計算好並寫到展示表中,直接通過展示表進行關聯,這樣鎖表也於業務表無關,關聯表也能變少達到減少CPU消耗的目的。

  3. iops與cpu佔比高導致資料庫癱瘓。第2點看出如果CPU高資料庫全SQL都會慢,IOPS也一樣。SQL慢會導致事務中的查詢慢,解放事務變慢了其他查詢就會鎖等待狀態變成堵塞。所以遇到大規模的查詢是否先查主鍵然後通過游標一個一個計算再進臨時表。這個是消耗時間和內存換CPU和IOPS的一個例子。反正伺服器資源最高怎樣開發應該是了解的,如何管制資源之間的平衡這個很重要。

舉個例子,部分MYSQL框架喜歡一次性把資料庫都導出來,然後減少子查詢,這個演算法針對有效的基礎數據這樣是可行的。針對業務數據應該沒人會用,但是基礎數據中也可能會存在海量的情況,比如坐標軌跡、省市區、電話號碼歸屬等。如果無腦應用這個框架會導致查詢起來很慢。

⑽ sql語句優化

with
t1as(
='1994-01-09'
unionall
='1994-01-01'
unionall
='倪'
unionall
='界'
),
t2as(

whereexists(selectnullfromt1wheret1.DomainPatientTID=DomainPatient.DomainPatientTID)
)
select*fromPIXPatientwhereexists(
selectnullfromt2wheret2.PIXPatientTID=PIXPatient.PIXPatientTID
);


僅LZ題目而言的最佳優化,沒有之一。

優化基本原則,in改成exists,將or改成union all,然後在不改變sql意思的情況下去掉distinct,union 改成union all。根據LZ的sql來看,去distinct,union 改成union all都不會影響sql的執行結果。


當然比如在oracle中,有些情況下in也是走可以走索引的,所以PatientBirthday = '1994-01-09' or PatientBirthday = '1994-01-01'也可以改為PatientBirthday in ('1994-01-09','1994-01-01'),這時候就不必再去把or改為union all。這個還需要看LZ環境實際情況。


另,不確定LZ的sql執行器是否支持WITH AS短語,不行的話再跟我講。