怎樣優化SQL語句的執行
環境:oracle 817 + linux + 陣列柜 swd_billdetail 表5000萬條數據 SUPER_USER 表2800條數據 連接列上都有索引,而且super_user中的一條對應于swd_billdetail表中的很多條記錄表與索引都做了分析。
實際應用的查詢為: select a。CHANNEL, B。
user_class from swd_billdetail B, SUPER_USER A where A。cn = B。
cn; 這樣在分析時導致查詢出的數據過多,不方便,所以用count(a。 CHANNEL||B。
user_class)來代替,而且count(a。CHANNEL||B。
user_class)操作本身并不占用過多的時間,所以可以接受此種替代。 利用索引查詢出SWD_BILLDETAIL表中所有記錄的方法 SQL> select count(id) from SWD_BILLDETAIL; COUNT(ID) ---------- 53923574 Elapsed: 00:02:166。
00 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=18051 Card=1) 1 0 SORT (AGGREGATE) 2 1 INDEX (FAST FULL SCAN) OF 'SYS_C001851' (UNIQUE) (Cost=18051 Card=54863946) Statistics ---------------------------------------------------------- 0 recursive calls 1952 db block gets 158776 consistent gets 158779 physical reads 1004 redo size 295 bytes sent via SQL*Net to client 421 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 1 rows processed 利用全表掃描從SWD_BILLDETAIL表中取出全部數據的方法。 SQL> select count(user_class) from swd_billdetail; COUNT(USER_CLASS) ----------------- 53923574 Elapsed: 00:11:703。
07 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=165412 Card=1 Bytes=2) 1 0 SORT (AGGREGATE) 2 1 TABLE ACCESS (FULL) OF 'SWD_BILLDETAIL' (Cost=165412 Card=54863946 Bytes=109727892) Statistics ---------------------------------------------------------- 0 recursive calls 8823 db block gets 1431070 consistent gets 1419520 physical reads 0 redo size 303 bytes sent via SQL*Net to client 421 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 1 rows processed select count(a。 CHANNEL||B。
user_class) from swd_billdetail B, SUPER_USER A where A。cn = B。
cn; EXEC_ORDER PLANLINE ---------- ----------------------------------------------------------------------------------------------------------- 6 SELECT STATEMENT OPT_MODE:CHOOSE (COST=108968,CARD=1,BYTES=21) 5 SORT (AGGREGATE) (COST=,CARD=1,BYTES=21) 4 NESTED LOOPS (COST=108968,CARD=1213745,BYTES=25488645) 1 TABLE ACCESS (FULL) OF 'SWORD。 SUPER_USER' (COST=2,CARD=2794,BYTES=27940) 3 TABLE ACCESS (BY INDEX ROWID) OF 'SWORD。
SWD_BILLDETAIL' (COST=39,CARD=54863946,BYTES=603503406) 2 INDEX (RANGE SCAN) OF 'SWORD。 IDX_DETAIL_CN' (NON-UNIQUE) (COST=3,CARD=54863946,BYTES=) 這個查詢耗費的時間很長,需要1個多小時。
運行后的信息如下: COUNT(A。CHANNEL||B。
USER_CLASS) ------------------------------ 1186387 Elapsed: 01:107:6429。 87 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=108968 Card=1 Bytes=21) 1 0 SORT (AGGREGATE) 2 1 NESTED LOOPS (Cost=108968 Card=1213745 Bytes=25488645) 3 2 TABLE ACCESS (FULL) OF 'SUPER_USER' (Cost=2 Card=2794Bytes=27940) 4 2 TABLE ACCESS (BY INDEX ROWID) OF 'SWD_BILLDETAIL' (Cost=39 Card=54863946 Bytes=603503406) 5 4 INDEX (RANGE SCAN) OF 'IDX_DETAIL_CN' (NON-UNIQUE) (Cost=3 Card=54863946) Statistics ---------------------------------------------------------- 0 recursive calls 4 db block gets 1196954 consistent gets 1165726 physical reads 0 redo size 316 bytes sent via SQL*Net to client 421 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 2 sorts (memory) 0 sorts (disk) 1 rows processed 將語句中加入hints,讓oracle的優化器使用嵌套循環,并且大表作為驅動表,生成新的執行計劃: select /*+ ORDERED USE_NL(A) */ count(a。
CHANNEL||B。user_class) from swd_billdetail B, SUPER_USER A where A。
cn = B。cn; EXEC_ORDER PLANLINE ---------- ----------------------------------------------------------------------------------------------------- 6 SELECT STATEMENT OPT_MODE:CHOOSE (COST=109893304,CARD=1,BYTES=21) 5 SORT (AGGREGATE) (COST=,CARD=1,BYTES=21) 4 NESTED LOOPS (COST=109893304,CARD=1213745,BYTES=25488645) 1 TABLE ACCESS (FULL) OF 'SWORD。
SWD_BILLDETAIL' (COST=165412,CARD=54863946,BYTES=603503406) 3 TABLE ACCESS (BY INDEX ROWID) OF 'SWORD。SUPER_USER。
怎么利用sql server日志查看執行的語句
--1.第一種測試方法
declare @begin datetime,@end datetime
set @begin =getdate()
{你所要測試的sql語句}
set @end=getdate()
PRINT DATEDIFF(millisecond, @begin, @end)/1000.0 --單位:s
--2.另一種測試方法(將執行每個語句時采取的步驟作為行集返回,通過層次結構樹的形式展示出來)
SET STATISTICS PROFILE ON:顯示分析、編譯和執行查詢所需的時間(以毫秒為單位)。
SET STATISTICS IO ON:報告與語句內引用的每個表的掃描數、邏輯讀取數(在高速緩存中訪問的頁數)和物理讀取數(訪問磁盤的次數)有關的信息。
SET STATISTICS TIME ON:顯示每個查詢執行后的結果集,代表查詢執行的配置文件。
SET STATISTICS profile on
SET STATISTICS io ON
SET STATISTICS time ON
go
---你要測試的sql語句
{你要測試的sql語句}
SET STATISTICS profile OFF
SET STATISTICS io OFF
SET STATISTICS time OFF
go
3.對SQL SERVER進行設置!!!!
{查詢-查詢選項-高級里,有個SET STATISTICS TIME勾上,然后執行SQL,看消息,就有執行時間了}
怎樣自動執行一段SQL語句
Oracle下:
1.新增一個批處理文件:如*
2.新增一個SQL腳本文件:如*
*中輸入:sqlplus 用戶名/密碼 @C:\*(假設*在c:盤根目錄下)
4.然后運行這個批處理,就可以執行這個sql腳本了.
假如:*的內容為:exec autojob;select * from *;select * from *;
那么就能逐語句執行.
SQL Server下:
isql -U 用戶名 -P 密碼 -i c:\*
同樣在bat文件中,輸入上面一行,在*輸入腳本.
如:
use 數據庫名
go
select * from 表名
go
如何查看SqlServer查詢語句的執行效率
使用語句查詢SQL Server執行過的語句及執行效率
SELECT TOP 1000
* AS '執行的SQL語句',
*ion_count AS '執行次數',
*_elapsed_time AS '耗時',
*_logical_reads AS '邏輯讀取次數',
*_logical_writes AS '邏輯寫入次數',
*_physical_reads AS '物理讀取次數',
*on_time AS '執行時間' ,
QS.*
FROM *_exec_query_stats QS
CROSS APPLY
*_exec_sql_text(*_handle) ST
--WHERE *on_time BETWEEN '2015-08-01 00:00:00' AND '2015-09-02 11:00:00'
ORDER BY
*on_time DESC
SQL語句是按什么順序執行的
分析器會先看語句的第一個詞,當它發現第一個詞是SELECT關鍵字的時候,它會跳到FROM關鍵字,然后通過FROM關鍵字找到表名并把表裝入內存。
接著是找WHERE關鍵字,如果找不到則返回到SELECT找字段解析,如果找到WHERE,則分析其中的條件,完成后再回到SELECT分析字段。 最后形成一張我們要的虛表。
其它的先不說了,只說WHERE。 WHERE關鍵字后面的是條件表達式。
如果學過C語言等編程語言就會知道,條件表達式計算完成后,會有一個返回值,即非0或0,非0即為真(true),0即為假(false)。同理WHERE后面的條件也有一個返回值,真或假,來確定接下來執不執行SELECT。
例: SELECT * FROM STUDENT WHERE SNO = '1'; 分析器先找到關鍵字SELECT,然后跳到FROM關鍵字將STUDENT表導入內存,并通過指針p1找到第一條記錄,接著找到WHERE關鍵字計算它的條件表達式,如果為真那么把這條記錄裝到一個虛表當中,p1再指向下一條記錄。 如果為假那么p1直接指向下一條記錄,而不進行其它操作。
一直檢索完整個表,關把虛表返回給用戶。 再說EXISTS謂詞,EXISTS謂詞也是條件表達式的一部分。
當然它也有一個返回值(true或false)。 例: SELECT Sname FROM Student WHERE EXISTS (SELECT * FROM SC WHERE SC。
Sno = Student。Sno AND SC。
Cno = '1'); 這是一個SQL語句的嵌套使用,但和上面說的SQL語句的執行過程也是相同的。嵌套的意思也就是說當分析主SQL語句(外面的那個SELECT,我們權且先這么叫它)到WHERE關鍵字的時候,又進入了另一個SQL語句中。
那么也就是說,分析器先找到表Student并裝入內存,一個指針(例如p1)指向Student表中的第一條記錄。然后進入WHERE里分析里面的SQL語句,再把SC表裝入內存,另一個指針(例如p2)指向SC表中的第一條記錄,分析WHERE后面的條件表達式,依次進行分析,最后分析出一個虛表2,也就變成 SELECT Sname FROM Student WHERE EXISTS 虛表2 如果虛表為空表,EXISTS 虛表2 也就為false,不返回到SELECT,而p1指向下一條記錄。
如果虛表2不為空也就是有記錄,那么EXISTS 虛表2 為true同,返回到SELECT并把p1指向的記錄添加到主SQL語句的虛表1當中。
轉載請注明出處華閱文章網 » sqlserver語句執行