如何測試sql語句性能,提高執行效率
有時候我們經常為我們的sql語句執行效率低下發愁,反復優化后,可還是得不到提高
那么你就用這條語句找出你sql到底是在哪里慢了
示例:
SET STATISTICS io ON
SET STATISTICS time
ON
go
---你要測試的sql語句
select top 100 * from
TBL_Cot_RecStaticList
go
SET STATISTICS profile
OFF
SET STATISTICS io OFF
SET STATISTICS time OFF
顯示信息:
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,占用時間 = 59 毫秒。
(100 行受影響) 表 'TBL_Cot_RecStaticList'。掃描計數 1,邏輯讀取 14 次,物理讀取 2
次,預讀 992 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
SQL Server 執行時間: CPU 時間 = 0 毫秒,占用時間 = 306 毫秒。
SQL Server 分析和編譯時間: CPU 時間 = 0 毫秒,占用時間 = 1 毫秒。
SQL Server 執行時間: CPU 時間 = 0 毫秒,占用時間 = 1 毫秒。
SQL Server 執行時間: CPU 時間 = 0 毫秒,占用時間 = 1 毫秒。
如何分析SQL語句 -
多時候,我們不太清楚自己寫的SQL語句好還是不好,往往數據量一大,程序運行變慢。
其實在SQL/PLUS里可以很清晰的分析出SQL語句的執行計劃,它可以提醒我們來創建索引或改變SQL語句的寫法。 先在sys用戶下運行@/ORACLE_HOME/sqlplus/admin/*內容:set echo ondrop role plustrace;create role plustrace;grant select on v_$sesstat to plustrace;grant select on v_$statname to plustrace;grant select on v_$session to plustrace;grant plustrace to dba with admin option;set echo off產生plustrace角色,然后在sys用戶下把此角色賦予一般用戶&usernameSQL> grant plustrace to &username; 然后找到/ORACLE_HOME/rdbms/admin/*,然后在當前用戶SQL>下運行,它創建一個plan_table,用來存儲分析SQL語句的結果。
create table PLAN_TABLE ( statement_id varchar2(30), timestamp date, remarks varchar2(80), operation varchar2(30), options varchar2(30), object_node varchar2(128), object_owner varchar2(30), object_name varchar2(30), object_instance numeric, object_type varchar2(30), optimizer varchar2(255), search_columns number, id numeric, parent_id numeric, position numeric, cost numeric, cardinality numeric, bytes numeric, other_tag varchar2(255), partition_start varchar2(255), partition_stop varchar2(255), partition_id numeric, other long, distribution varchar2(30)); 在SQL/PLUS的窗口運行以下命令 set time on; (說明:打開時間顯示) set autotrace on; (說明:打開自動分析統計,并顯示SQL語句的運行結果) set autotrace traceonly; (說明:打開自動分析統計,不顯示SQL語句的運行結果) 接下來你就運行測試SQL語句,看到其分析統計結果了。一般來講,我們的SQL語句應該避免對大表的全表掃描。
關閉以上功能,在SQL/PLUS的窗口運行以下命令 set time off; (說明:關閉時間顯示) set autotrace off; (說明:關閉自動分析統計)。
詢問sql語句優化測試方法以下2句怎么測試出哪句性能更好?sel - 愛問
這兩個SQL語句看起來都未能使用上索引,都是tablescan表掃操作,但是第一個SQL語句用了兩個LIKE,一個NULL的判斷。
一般情況下,IS NOT NULL比IS NULL的判斷更耗費資源。第二個SQL語句用了+運算和一個LIKE,好象比第一個性能要好一些。
但是當我在ASA中,隨意造了一個將近60萬條數據的堆表后,分別在PB中執行Explain SQL,分別顯示上面兩個SQL語句的執行計劃如下(表名我用的是test,字段分別是aa,bb): 1:( Plan [ Total Cost Estimate: 32.96008 ] ( TableScan test[ ( ( * >= '' : 100% Statistics ) AND ( * LIKE '%轉讓%' : 100% Computed ) ) OR ( ( >= '' : 100% Statistics ) AND ( LIKE '%轉讓%' : 100% Computed ) ) : 100% Combined ] ) ) 2:( Plan [ Total Cost Estimate: 32.96008 ] ( TableScan test[ ( expr( *, ) >= '' : 25% Guess ) AND ( expr( *, ) LIKE '%轉讓%' : 100% Computed ) ] ) ) 結果是兩個SQL語句的Total Cost Estimate都是一樣,所以直接從表面上看,很難判斷究竟哪個SQL性能更優,建議最好能夠在實際執行環境中測試一下。當然WHERE條件越簡單,并且能夠優化使用上索引是最好的!。
SQL語句練習,求全部語句
-------創庫
create database EDUC
-------創表
create table student
(
id nchar(12),
name nchar(4),
sex char(2),
birthday smalldatetime,
part_id char(8)
)
1.0
insert into student(id,name,sex,birthday,part_id)
values('2016110011','張三' 。。. )
計算機二級考試中常用的命令語句和SQL語句
例如,可用下列語法在 JDBC SQL 語句中指定日期: {d `yyyy-mm-dd'} 在該語法中,yyyy 為年代,mm 為月份,而 dd 則為日期。
驅動程序將用等價的特定于 DBMS 的表示替換這個轉義子句。例如,如果 '28- FEB-99' 符合基本數據庫的格式,則驅動程序將用它替換 {d 1999-02-28}。
對于 TIME 和 TIMESTAMP 也有類似的轉義子句: {t `hh:mm:ss'} {ts `yyyy-mm-dd hh:mm:ss.f . . .'} TIMESTAMP 中的小數點后的秒(.f . . .)部分可忽略。 call 或 ? = call 表示已存儲過程 如果數據庫支持已存儲過程,則可從 JDBC 中調用它們,語法為: {call procedure_name[(?, ?, . . .)]} 或(其中過程返回結果參數): {? = call procedure_name[(?, ?, . . .)]} 方括號指示其中的內容是可選的。
它們不是語法的必要部分。 輸入參數可以為文字或參數。
有關詳細信息,參見 JDBC 指南中第 7 節,“CallableStatement”。 可通過調用方法 *tsStoredProcedures 檢查數據庫是否支持已存儲過程。
oj 表示外部連接 外部連接的語法為 {oj outer-join} 其中 outer-join 形式為 table LEFT OUTER JOIN {table / outer-join} ON search-condition 外部連接屬于高級功能。有關它們的解釋可參見 SQL 語法。
JDBC 提供了三種 DatabaseMetaData 方法用于確定驅動程序支持哪些外部連接類型:supportsOuterJoins、supportsFullOuterJoins 和 supportsLimitedOuterJoins。 方法 *apeProcessing 可打開或關閉轉義處理;缺省狀態為打開。
當性能極為重要時,程序員可能想關閉它以減少處理時間。但通常它將出于打開狀態。
應注意: setEscapeProcessing 不適用于 PreparedStatement 對象,因為在調用該語句前它就可能已被發送到數據庫。有關預編譯的信息,參見 PreparedStatement。
6、使用方法 execute execute 方法應該僅在語句能返回多個 ResultSet 對象、多個更新計數或 ResultSet 對象與更新計數的組合時使用。當執行某個已存儲過程或動態執行未知 SQL 字符串(即應用程序程序員在編譯時未知)時,有可能出現多個結果的情況,盡管這種情況很少見。
例如,用戶可能執行一個已存儲過程(使用 CallableStatement 對象 - 參見第 135 頁的 CallableStatement),并且該已存儲過程可執行更新,然后執行選擇,再進行更新,再進行選擇,等等。通常使用已存儲過程的人應知道它所返回的內容。
因為方法 execute 處理非常規情況,所以獲取其結果需要一些特殊處理并不足為怪。例如,假定已知某個過程返回兩個結果集,則在使用方法 execute 執行該過程后,必須調用方法 getResultSet 獲得第一個結果集,然后調用適當的 getXXX 方法獲取其中的值。
要獲得第二個結果集,需要先調用 getMoreResults 方法,然后再調用 getResultSet 方法。如果已知某個過程返回兩個更新計數,則首先調用方法 getUpdateCount,然后調用 getMoreResults,并再次調用 getUpdateCount。
對于不知道返回內容,則情況更為復雜。如果結果是 ResultSet 對象,則方法 execute 返回 true;如果結果是 Java int,則返回 false。
如果返回 int,則意味著結果是更新計數或執行的語句是 DDL 命令。在調用方法 execute 之后要做的第一件事情是調用 getResultSet 或 getUpdateCount。
調用方法 getResultSet 可以獲得兩個或多個 ResultSet 對象中第一個對象;或調用方法 getUpdateCount 可以獲得兩個或多個更新計數中第一個更新計數的內容。 當 SQL 語句的結果不是結果集時,則方法 getResultSet 將返回 null。
這可能意味著結果是一個更新計數或沒有其它結果。在這種情況下,判斷 null 真正含義的唯一方法是調用方法 getUpdateCount,它將返回一個整數。
這個整數為調用語句所影響的行數;如果為 -1 則表示結果是結果集或沒有結果。如果方法 getResultSet 已返回 null(表示結果不是 ResultSet 對象),則返回值 -1 表示沒有其它結果。
也就是說,當下列條件為真時表示沒有結果(或沒有其它結果): ((*ultSet() == null) && (*ateCount() == -1)) 如果已經調用方法 getResultSet 并處理了它返回的 ResultSet 對象,則有必要調用方法 getMoreResults 以確定是否有其它結果集或更新計數。如果 getMoreResults 返回 true,則需要再次調用 getResultSet 來檢索下一個結果集。
如上所述,如果 getResultSet 返回 null,則需要調用 getUpdateCount 來檢查 null 是表示結果為更新計數還是表示沒有其它結果。 當 getMoreResults 返回 false 時,它表示該 SQL 語句返回一個更新計數或沒有其它結果。
因此需要調用方法 getUpdateCount 來檢查它是哪一種情況。在這種情況下,當下列條件為真時表示沒有其它結果: ((*eResults() == false) && (*ateCount() == -1)) 下面的代碼演示了一種方法用來確認已訪問調用方法 execute 所產生的全部結果集和更新計數: *e(queryStringWithUnknownResults); while (true) { int rowCount = *ateCount(); if (rowCount > 0) { // 它是更新計數 *n("Rows changed = " + count); *eResults(); continue; } if (。
SQL語句查詢結果作為第二個語句的表格
--創建測試表 這里需要問一下你后面你篩選的name 和no 的列名有1,2,3嗎?
CREATE TABLE #T
(
name VARCHAR(20) ,
no VARCHAR(10)
)
DECLARE @name VARCHAR(20)= ''
DECLARE @str NVARCHAR(100)
--創建游標
DECLARE cursor_tb CURSOR FAST_FORWARD
FOR
( SELECT tablename
FROM tablemain
)
OPEN cursor_tb
FETCH NEXT FROM cursor_tb
INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @str = 'select name,no from '
+ QUOTENAME(@name)
INSERT INTO #T EXEC(@sql);
FETCH NEXT FROM cursor_tb
INTO @name
END
CLOSE cursor_tb
DEALLOCATE cursor_tb
SELECT *
FROM #T
--刪除臨時表
DROP TABLE #T