Ⅰ 誰能講講sql硬軟解析的區別
Oracle SQL的硬解析和軟解析
我們都知道在Oracle中每條SQL語句在執行之前都需要經過解析,這裡面又分為軟解析和硬解析。在Oracle中存在兩種類型的SQL語句,一類為DDL語句(數據定義語言),他們是從來不會共享使用的,也就是每次執行都需要進行硬解析。還有一類就是DML語句(數據操縱語言),他們會根據情況選擇要麼進行硬解析,要麼進行軟解析。
DML:INSERT,UPDATE,DELETE,SELECT
DDL:CREATE,DROP,ALTER
一.SQL解析過程
Oracle對此SQL將進行幾個步驟的處理過程:
1、語法檢查(syntaxcheck):檢查此sql的拼寫是否語法。
2、語義檢查(semanticcheck):諸如檢查sql語句中的訪問對象是否存在及該用戶是否具備相應的許可權。
3、對sql語句進行解析(prase):利用內部演算法對sql進行解析,生成解析樹(parsetree)及執行計劃(executionplan)。
4、執行sql,返回結果(executeandreturn)
二.解析過程詳解
2.1語法檢測
判斷一條SQL語句的語法是否符合SQL的規范,比如執行:
SQL>selet*fromemp;
我們就可以看出由於Select關鍵字少了一個「c」,這條語句就無法通過語法檢驗的步驟了。
2.2語義檢查
語法正確的SQL語句在解析的第二個步驟就是判斷該SQL語句所訪問的表及列是否准確?用戶是否有許可權訪問或更改相應的表或列?比如如下語句:
SQL>select*fromemp;
select*fromemp
*
ERRORatline1:
ORA-00942:tableorviewdoesnotexist
由於查詢用戶沒有可供訪問的emp對象,因此該SQL語句無法通過語義檢查。
2.3解析(Parse)
2.3.1Parse主要分為三種:
1、HardParse(硬解析)
2、SoftParse(軟解析)
3、SoftSoftParse(好像有些資料中並沒有將這個算在其中)
HardParse:就是上面提到的對提交的Sql完全重新從頭進行解析(當在SharedPool中找不到時候將會進行此操作),總共有一下5個執行步驟:
1:語法分析
2:許可權與對象檢查
3:在共享池中檢查是否有完全相同的之前完全解析好的.如果存在,直接跳過4和5,運行Sql,此時算softparse.
4:選擇執行計劃
5:產生執行計劃
註:創建解析樹、生成執行計劃對於sql的執行來說是開銷昂貴的動作,所以,應當極力避免硬解析,盡量使用軟解析。這就是在很多項目中,倡導開發設計人員對功能相同的代碼要努力保持代碼的一致性,以及要在程序中多使用綁定變數的原因。
SoftParse:就如果是在SharedPool中找到了與之完全相同的Sql解析好的結果後會跳過HardParse中的後面的兩個步驟。
SoftSoftParse:實際上是當設置了session_cursor_cache這個參數之後,Cursor被直接Cache在當前Session的PGA中的,在解析的時候只需要對其語法分析、許可權對象分析之後就可以轉到PGA中查找了,如果發現完全相同的Cursor,就可以直接去取結果了,也就就是實現了SoftSoftParse.
2.3.2解析的步驟可以分為兩個步驟:
1)驗證SQL語句是否完全一致。
在這個步驟中,Oracle將會對傳遞進來的SQL語句使用HASH函數運算得出HASH值,再與共享池中現有語句的HASH值進行比較看是否一一對應。現有資料庫中SQL語句的HASH值我們可以通過訪問vsqlarea、v$sqltext等數據字典中的HASH_VALUE列查詢得出。
如果SQL語句的HASH值一致,那麼ORACLE事實上還需要對SQL語句的語義進行再次檢測,以決定是否一致。那麼為什麼Oracle需要再次對語句文本進行檢測呢?不是SQL語句的HASH值已經對應上了?事實上就算是SQL語句的HASH值已經對應上了,並不能說明這兩條SQL語句就已經可以共享了。
例如:假如用戶SYS有自己的一張表EMP,他要執行查詢語句:select*fromemp;用戶SYSTEM也有一張EMP表,同樣要查詢select*fromemp;這樣他們兩條語句在文本上是一模一樣的,他們的HASH值也會一樣,但是由於涉及到查詢的相關表不一樣,他們事實上是無法共享的.
SQL>conn/assysdba
已連接。
SQL>showuser
USER為"SYS"
SQL>createtableemp(xint);
表已創建。
SQL>select*fromemp;
未選定行
SQL>connsystem/admin;
已連接。
SQL>createtableemp(xint);
表已創建。
SQL>select*fromemp;
未選定行
SQL>selectaddress,hash_value,executions,sql_textfromv$sqlwhereupper(sql_text)like'SELECT*FROMEMP%';
ADDRESSHASH_VALUEEXECUTIONSSQL_TEXT
--------------------------------------------------------------------------------
2769AE6417457007751select*fromemp
2769AE6417457007751select*fromemp
2rowsselected.
從結果可以看到這2個查詢的語句文本和HASH值都是一樣的,但是由於查詢的對象不同,是無法共享的,不同情況的語句還是需要硬解析的。因此在檢查共享池共同SQL語句的時候,是需要根據具體情況而定的。
可以進一步查詢v$sql_shared_cursor以得知SQL為何不能共享的原因:
SQL>selectaddress,auth_check_mismatch,translation_mismatch,optimizer_mismatch
fromv$sql_shared_cursorwhereaddressin(
selectaddressfromv$sqlwhereupper(sql_text)like'SELECT*FROMEMP%')
ADDRESSATO
-------------------------
2769AE64NNN
2769AE64YYN
TRANSLATION_MISMATCH表示SQL游標涉及到的數據對象是不同的;
AUTH_CHECK_MISMATCH表示對同樣一條SQL語句轉換是不匹配的。
optimizer_mismatch表示會話的優化器環境是不同的。
2)驗證SQL語句執行環境是否相同
比如同樣一條SQL語句,一個查詢會話加了/*+first_rows*/的HINT,另外一個用戶加/*+all_rows*/的HINT,他們就會產生不同的執行計劃,盡管他們是查詢同樣的數據。
通過如上檢查以後,如果SQL語句是一致的,那麼就會重用原有SQL語句的執行計劃和優化方案,也就是我們通常所說的軟解析。如果SQL語句沒有找到同樣的副本,那麼就需要進行硬解析了。
Oracle根據提交的SQL語句再查詢相應的數據對象是否有統計信息。如果有統計信息的話,那麼CBO將會使用這些統計信息產生所有可能的執行計劃(可能多達成千上萬個)和相應的Cost,最終選擇Cost最低的那個執行計劃。如果查詢的數據對象無統計信息,則按RBO的默認規則選擇相應的執行計劃。這個步驟也是解析中最耗費資源的,因此我們應該極力避免硬解析的產生。至此,解析的步驟已經全部完成,Oracle將會根據解析產生的執行計劃執行SQL語句和提取相應的數據。
2.4執行sql,返回結果(executeandreturn)
三.綁定變數
使用了BindVar能提高性能主要是因為這樣做可以盡量避免不必要的硬分析(HardParse)而節約了時間,同時節約了大量的CPU資源。
當一個Client提交一條Sql給Oracle後,Oracle首先會對其進行解析(Parse),然後將解析結果提交給優化器(Optimiser)來進行優化而取得Oracle認為的最優的QueryPlan,然後再按照這個最優的Plan來執行這個Sql語句(當然在這之中如果只需要軟解析的話會少部分步驟)。
但是,當Oracle接到Client提交的Sql後會首先在共享池(SharedPool)裡面去查找是否有之前已經解析好的與剛接到的這一個Sql完全相同的Sql(注意這里說的是完全相同,既要求語句上的字元級別的完全相同,又要求涉及的對象也必須完全相同)。當發現有相同的以後解析器就不再對新的Sql在此解析而直接用之前解析好的結果了。這里就節約了解析時間以及解析時候消耗的CPU資源。尤其是在OLTP中運行著的大量的短小Sql,效果就會比較明顯了。因為一條兩條Sql的時間可能不會有多少感覺,但是當量大了以後就會有比較明顯的感覺了。
Ⅱ sql語句的解析順序
對於該SQL語句,由於語句里同時存在where和top語句的,並且where條件列不是合適的索引,程序執行的是全表掃描,首先是查找符合where條件的記錄, 而這里的top限制形同虛設。如果全表是百萬級別以上的數據表,那麼就這么一個簡單的判斷,就有可能拖垮資料庫。
所以需要先把符合「where條件」的記錄,用一個子查詢篩選出來,再在篩選結果集里選top30。
Ⅲ 請教一段SQL語句的含義
select
a.splanno,a.addid,a.itemno,
b.itemname,b.descript,
c.msname,
a.planqty,a.plansum,a.rcvqty,a.rcvsum,
a.planqty - a.rcvqty celqty,
a.plansum - a.rcvsum celsum
from
(
select
a.splanno,a.addid,a.itemno,
sum(isnull(a.planqty,0)) planqty,sum(isnull(a.plansum,0)) plansum,sum(isnull(a.rcvqty,0)) rcvqty,
sum(isnull(a.untaxrcvsum,0)) rcvsum
from
(select
a.splanno,case when a.addid = 1 then 1 when a.addid > 1 then 2 end addid,
a.itemno,a.planqty,a.plansum,a.spurno,a.lineid,b.rcvqty,
b.untaxrcvsum from
(select a.splanno,a.addid,a.itemno,a.planqty,a.plansum,b.spurno,b.lineid from
(select splanno,addid,itemno,planqty,plansum plansum from purplandet
where splanno in (select distinct splanno from purplanmst where cyc_code='0004')) a
left outer join
purdec b
on a.splanno=b.refsysno and a.addid=b.refaddsysno and a.itemno=b.itemno
) a
left outer join
rcvdet b
on a.spurno=b.purno and a.lineid=b.refrow and a.itemno=b.itemno
) a
group by a.splanno,a.addid,a.itemno
) a,
itemdata b,msunit c
where a.itemno=b.itemno and b.msunit=c.msunit
order by a.splanno,a.addid,a.itemno
1.先對SQl語句進行整理提高可讀性
2.針對幾個簡單的概念和簡單函數先了解
(a).別名(表的別名 以及欄位的別名):
上述例子中 如itemdata b 即定義表itemdata 為名稱b 這樣在第一個select中b.itemname即是查詢的為itemdata.itemname
a.planqty - a.rcvqty celqty就是對前面的計算結果 以celqty欄位名稱作為顯示
(b).isnull
如果第一個參數值為空,默認顯示第二個欄位值
(c).sum
欄位加總
(d).left join
表關聯,配合on條件
(e).group by
分組欄位
(f).case when
SQL中的if else
3.SQL解析(因為不知道你的表具體含義只能通過SQL單純的看)
(a). 一層一層來看的話,最外層查詢的含義是
查詢第一層子查詢中的splanno,addid,itemno,
planqty,plansum,arcvqty,rcvsum,planqty - rcvqty,
plansum - rcvsum
以及itemdata 中的itemname,descript,和msunit表中的msname,
a表是通過itemno和itemdata 表關聯,itemdata 表再通過msunit和msunit表關聯
最後按照a表中splanno,addid,itemno進行升序排序
(b).from里層主要是查詢最外層所定義的a表
(b1).直接看最里層的SQL查詢
select a.splanno,a.addid,a.itemno,a.planqty,a.plansum,b.spurno,b.lineid from
(select splanno,addid,itemno,planqty,plansum plansum from purplandet
where splanno in (select distinct splanno from purplanmst where cyc_code='0004')) a
left outer join
purdec b
on a.splanno=b.refsysno and a.addid=b.refaddsysno and a.itemno=b.itemno) a
查詢purplandet 中splanno 對應的cyc_code為0004的相關資料並關聯purdec 查詢對應欄位
(b2).以上查詢出後會在關聯rcvdet 查出需要欄位
(b3).通過對a.splanno,a.addid,a.itemno的分組,統計對應欄位的加總信息
不知道這樣說明是否OK? 另外 建議盡量避免子查詢 會影響效能
~~排版有點亂 湊合著看吧
Ⅳ sql 解析字元串
update av set string=convert(varchar,left(string,charindex(';',string)-1)+1)+right(string,len(string)-charindex(';',string)+1)
我試了一下,在SQL SERVER上沒問題,你是什麼資料庫?
如果出現錯誤,有可能是 分號; ,我用的是英文的分號,有可能你的資料庫中是中文的分號
Ⅳ sql數據分析是啥意思
sql數據分析是結構化查詢語言。
結構化查詢語言(Structured Query Language)簡稱SQL,是一種特殊目的的編程語言,是一種資料庫查詢和程序設計語言,用於存取數據以及查詢、更新和管理關系資料庫系統。
結構化查詢語言是高級的非過程化編程語言,允許用戶在高層數據結構上工作。它不要求用戶指定對數據的存放方法,也不需要用戶了解具體的數據存放方式。
所以具有完全不同底層結構的不同資料庫系統, 可以使用相同的結構化查詢語言作為數據輸入與管理的介面。結構化查詢語言語句可以嵌套,這使它具有極大的靈活性和強大的功能。
SQL具有數據定義、數據操縱、數據查詢和數據控制的功能。
1、SQL數據定義功能:能夠定義資料庫的三級模式結構,即外模式、全局模式和內模式結構。在SQL中,外模式又叫做視圖(View),全局模式簡稱模式(Schema),內模式由系統根據資料庫模式自動實現,一般無需用戶過問。
2、SQL數據操縱功能:包括對基本表和視圖的數據插入、刪除和修改,特別是具有很強的數據查詢功能。
3、SQL的數據控制功能:主要是對用戶的訪問許可權加以控制,以保證系統的安全性。
Ⅵ SQL語句分析是什麼意思啊
究竟在哪裡有問題呀,說明白點?
Ⅶ 關於SQL的解析
注,為了邏輯清晰,分解成多條SQL中
1、
1.1, 先按客戶進行廣告收入進行統計
---
大段的SQL 代碼居然無法提交:(
而且,現在編輯器已經無法插入代碼了,網路問答實在太爛了!
Ⅷ sql語句執行過程中會解析成二進制位被計算機識別嗎在哪一個階段被解析的
會解析成二進制的,和電腦交互的時候被解析的。
Ⅸ sql語句求詳細解析如下 需要對每一句解釋是什麼意思 如果注冊的用戶數
as 一般用在兩個地方,一個是query的時候,用來重新指定返回的column 名字如:一個table 有個column叫 id, 我們的query是select id from table1. 但是如果你不想叫id了,就可以重新命名,如叫 systemID 就可以這樣寫select id as systemId from table1;還有一個用法就是在create table 或 procere 的時候,as 是個關鍵字。例如create table test as select * from table1這時候就會create 一個table test,他是完全 table table1里的全部數據。create procre name as (is)beginend;具體可以參考 如何建立procere。 這個時候 as 和is可以互換。