国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

PostgreSQL中的查詢:1.查詢執(zhí)行階段

微云疏影 ? 來(lái)源:yzsDBA ? 作者:yzsDBA ? 2023-01-24 16:44 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

PostgreSQL中的查詢:1.查詢執(zhí)行階段

開(kāi)始關(guān)于PG內(nèi)部執(zhí)行機(jī)制的文章系列。這一篇側(cè)重于查詢計(jì)劃和執(zhí)行機(jī)制。

本系列包括:

1、查詢執(zhí)行階段(本文)

2、統(tǒng)計(jì)數(shù)據(jù)

3、順序掃描

4、索引掃描

5、嵌套循環(huán)連接

6、哈希連接

7、Merge join

本系列針對(duì)PG14編寫(xiě)。

簡(jiǎn)單查詢協(xié)議

PG客戶端-服務(wù)協(xié)議的基本目的是雙重的:將SQL查詢發(fā)送到服務(wù),接收整個(gè)執(zhí)行結(jié)果作為響應(yīng)。服務(wù)接收到查詢?nèi)?zhí)行要經(jīng)過(guò)幾個(gè)階段。

解析

首先,需要解析查詢文本,這樣服務(wù)才能準(zhǔn)確了解需要執(zhí)行什么。

詞法分析器和解析器。詞法解析器負(fù)責(zé)識(shí)別查詢字符串中的詞位(如SQL關(guān)鍵字、字符串、數(shù)字文字等),而解析器確保生成的詞位集在語(yǔ)法上是有效的。解析器和詞法解析器使用標(biāo)準(zhǔn)工具Bison和Flex實(shí)現(xiàn)。解析的查詢表示位抽象的語(yǔ)法樹(shù)。例如:

image.png

在這里,將在后臺(tái)內(nèi)存中構(gòu)建一棵樹(shù)。下面以高度簡(jiǎn)化的形式表示該樹(shù)。樹(shù)中節(jié)點(diǎn)用查詢的相應(yīng)部分標(biāo)記:

pYYBAGO2jdaAMZmNAABeaGtAANA430.jpg

RTE是一個(gè)晦澀的縮寫(xiě),表示“范圍表?xiàng)l目”。PG源碼中“range table”指***查詢、連接結(jié)果--也就是說(shuō)SQL語(yǔ)句操作的任何記錄集。

語(yǔ)法分析器。語(yǔ)法分析器確定數(shù)據(jù)庫(kù)中是否存在查詢中引用的表和其他對(duì)象,用戶是否有訪問(wèn)這些對(duì)象的權(quán)限。語(yǔ)法分析需要的所有信息都在系統(tǒng)catalog中。

語(yǔ)法分析接收分析器傳來(lái)的解析樹(shù)并重新構(gòu)建它,并用引用的特定數(shù)據(jù)庫(kù)對(duì)象、數(shù)據(jù)類(lèi)型信息等來(lái)補(bǔ)充它。如果開(kāi)啟debug_right_parse,則會(huì)在服務(wù)消息日志中顯示完整的樹(shù)信息,盡管這沒(méi)什么實(shí)際意義。

轉(zhuǎn)換

下一步,對(duì)查詢進(jìn)行重寫(xiě)。

系統(tǒng)內(nèi)核將重寫(xiě)用于多種目的。其中之一是將解析樹(shù)中的視圖名替換為該視圖查詢相對(duì)應(yīng)的子樹(shù)。pg_tables是上面例子的一個(gè)視圖,重寫(xiě)后的解析樹(shù)將采用以下形式:

poYBAGO2jdeAUB4HAAB8zpbg54g183.jpg

解析樹(shù)對(duì)應(yīng)的查詢(經(jīng)所有操作僅在樹(shù)上執(zhí)行,而不是在查詢文本上執(zhí)行):

image.png

解析樹(shù)反映查詢的語(yǔ)法結(jié)構(gòu),而不是執(zhí)行操作的順序。行級(jí)安全性在轉(zhuǎn)換階段實(shí)施。

系統(tǒng)核心使用重寫(xiě)的另一個(gè)例子是版本14中遞歸查詢的SEARCH和CYCLE子句中實(shí)現(xiàn)。

PG支持自定義轉(zhuǎn)換,用戶可以使用重寫(xiě)規(guī)則系統(tǒng)來(lái)實(shí)現(xiàn)。規(guī)則系統(tǒng)作為PG主要功能之一。這些規(guī)則得到了項(xiàng)目基礎(chǔ)的支持,并在早期開(kāi)發(fā)過(guò)程中反復(fù)重新設(shè)計(jì)。這是一個(gè)強(qiáng)大的機(jī)制,但難以理解和調(diào)試。甚至有人提議將規(guī)則從PG中完全刪除,但沒(méi)有得到普遍支持。在大多數(shù)情況下,使用觸發(fā)器而不是規(guī)則更安全、更方便。

如果debug_print_rewritten開(kāi)啟,則完整重寫(xiě)的解析樹(shù)會(huì)顯示在服務(wù)消息日志中。

計(jì)劃

SQL是一種聲明性語(yǔ)言:查詢指定要檢索什么,但不指定如何檢索它。任何查詢都可以通過(guò)多種方式執(zhí)行。解析樹(shù)中的每個(gè)操作都有多個(gè)執(zhí)行選項(xiàng)。例如,您可以通過(guò)讀取整個(gè)表并丟棄不需要的行來(lái)從表中檢索特定記錄,或者可以使用索引來(lái)查詢與您查詢匹配的行。數(shù)據(jù)集總是成對(duì)連接。連接順序的變化會(huì)產(chǎn)生大量執(zhí)行選項(xiàng)。然后有許多方法可以將2組行連接在一起。例如,您可以逐個(gè)遍歷第一個(gè)集合中的行,并在另一個(gè)集合中查找匹配的行,或者您可以先對(duì)2個(gè)集合進(jìn)行排序,然后將他們合并在一起。不同方法在某些情況下表現(xiàn)更好,在另一些情況下表現(xiàn)更差。

最佳計(jì)劃的執(zhí)行速度可能比非最佳計(jì)劃快幾個(gè)數(shù)量級(jí),這就是為什么優(yōu)化解析查詢的執(zhí)行計(jì)劃器是系統(tǒng)最復(fù)雜的元素之一。

計(jì)劃樹(shù)。執(zhí)行計(jì)劃也可以表示為樹(shù),但其節(jié)點(diǎn)是對(duì)數(shù)據(jù)的物理操作而不是邏輯操作。

poYBAGO2jdiAFJHkAABJQG6XjGw126.jpg

開(kāi)啟debug_print_plan,則整個(gè)執(zhí)行計(jì)劃樹(shù)會(huì)顯示在服務(wù)消息日志中。這是非常不切實(shí)際的,因?yàn)槿罩痉浅;靵y。更方便的選擇是使用EXPLAIN命令:

EXPLAIN

SELECT schemaname, tablename

FROM pg_tables

WHERE tableowner = 'postgres'

ORDER BY tablename;

QUERY PLAN?????????????????????????????????????????????????????????????????????

Sort (cost=21.03..21.04 rows=1 width=128)

Sort Key: c.relname

?> Nested Loop Left Join (cost=0.00..21.02 rows=1 width=128)

Join Filter: (n.oid = c.relnamespace)

?> Seq Scan on pg_class c (cost=0.00..19.93 rows=1 width=72)

Filter: ((relkind = ANY ('{r,p}'::"char"[])) AND (pg_g...

?> Seq Scan on pg_namespace n (cost=0.00..1.04 rows=4 wid...

(7 rows)

該圖顯示了樹(shù)的主要節(jié)點(diǎn)。相同的節(jié)點(diǎn)在EXPLAIN輸出中使用箭頭標(biāo)記。Seq Scan節(jié)點(diǎn)表示讀取表操作,而Nested Loop節(jié)點(diǎn)表示表連接操作。這里有2個(gè)優(yōu)趣的點(diǎn)需要注意:

1) 其中一個(gè)初始化表從執(zhí)行計(jì)劃樹(shù)中消失了,因?yàn)閳?zhí)行計(jì)劃器指出查詢處理中不需要它

2) 估算要處理的行數(shù)和每個(gè)節(jié)點(diǎn)處理的代價(jià)

計(jì)劃查詢。為找到最佳計(jì)劃,PG使用基于成本的查詢優(yōu)化器。優(yōu)化器會(huì)檢查各種可用的執(zhí)行計(jì)劃并估算需要的資源量,例如IO周期和CPU周期。這個(gè)計(jì)算出的估算值轉(zhuǎn)換成任意單位,被稱(chēng)為計(jì)劃成本。選擇結(jié)果成本最低的計(jì)劃來(lái)執(zhí)行。

問(wèn)題是,可能的計(jì)劃數(shù)量隨著連接數(shù)量的增加而呈指數(shù)增長(zhǎng),即使對(duì)于相對(duì)簡(jiǎn)單的查詢,也無(wú)法一一篩選所有計(jì)劃。因此,使用動(dòng)態(tài)規(guī)劃和啟發(fā)式限制搜索范圍。這允許在合理的時(shí)間內(nèi)精確第解決查詢中更多表的問(wèn)題,但不能保證所選的計(jì)劃是真正最優(yōu)的。因?yàn)橛?jì)劃其使用簡(jiǎn)化的數(shù)學(xué)模型并可能使用不精確的初始化數(shù)據(jù)。

Ordering joins:可以以特定方式構(gòu)建查詢,以顯著縮小搜索范圍(有可能錯(cuò)過(guò)找到最佳計(jì)劃的機(jī)會(huì)):

1) 公共表表達(dá)式通常與主查詢分開(kāi)優(yōu)化。從12開(kāi)始可以使用MATERIALIZE子句來(lái)強(qiáng)制執(zhí)行此操作。

2) 來(lái)自非SQL函數(shù)的查詢和主查詢分開(kāi)優(yōu)化。(在某些情況下,SQL函數(shù)可以內(nèi)聯(lián)到主查詢中)

3) join_collapse_limit參數(shù)與現(xiàn)式j(luò)oin子句以及from_collapse_limit參數(shù)與子查詢一起可以定義某些連接順序,具體取決于查詢語(yǔ)法。

最后一個(gè)可能需要解釋?zhuān)旅娴牟樵冋{(diào)用FROM子句中的幾個(gè)表,沒(méi)有顯式連接:

SELECT ...FROM a, b, c, d, eWHERE ...

下面是此查詢的解析樹(shù):

pYYBAGO2jdiAYtYcAAAjzwQitmY713.jpg

在這個(gè)查詢中,規(guī)劃器將考慮所有可能的連接順序。在下一個(gè)示例中,一些連接由JOIN子句顯式定義:

SELECT ...FROM a, b JOIN c ON ..., d, eWHERE ...

解析樹(shù)反映了這一點(diǎn):

pYYBAGO2jdiATpb7AAAfGybufw4821.jpg

規(guī)劃器折疊連接樹(shù),有效地將其轉(zhuǎn)換為上一個(gè)示例中的樹(shù)。該算法遞歸地遍歷樹(shù)并用其組件的平面列表替換每個(gè)JOINEXPR節(jié)點(diǎn)。

但是只有在生成的屏幕列表包含不超過(guò)join_collapse_limit個(gè)元素(默認(rèn)8個(gè))時(shí),才會(huì)發(fā)生這種“扁平化”。在上面示例中,如果將join_collapse_limit設(shè)置5或更少,則不會(huì)折疊JOINEXPR節(jié)點(diǎn)。對(duì)于規(guī)劃器來(lái)說(shuō),這意味著兩件事:表B必須連接到表C(反之亦然,join對(duì)中的join 順序不受限制);表A、D、E以及B到C的連接可以按任意順序連接。

如果join_collapse_limit設(shè)置為1,則將保留任何顯式JOIN順序。注意,無(wú)論該參數(shù)如何,操作FULL OUTER JOIN都不會(huì)折疊。

參數(shù)from_collapse_limit(默認(rèn)也是8)以類(lèi)似的方式限制子查詢的展平。子查詢似乎與連接沒(méi)有太多共同之處,但當(dāng)它歸結(jié)為解析樹(shù)級(jí)別時(shí),相似性顯而易見(jiàn)。

例子:

SELECT ...FROM a, b JOIN c ON ..., d, eWHERE ...

下面是對(duì)應(yīng)樹(shù):

poYBAGO2jdmAEo4LAAAwkmpVRyQ005.jpg

這里唯一的區(qū)別是JOINEXPR節(jié)點(diǎn)被替換成FROMEXPR(因此參數(shù)名稱(chēng)為FROM)。

遺傳搜索:每當(dāng)生成的扁平樹(shù)以太多相同級(jí)別的節(jié)點(diǎn)(表或連接結(jié)果)結(jié)束時(shí),規(guī)劃時(shí)間可能會(huì)飆升,因?yàn)槊總€(gè)節(jié)點(diǎn)都需要單獨(dú)優(yōu)化。如果geqo參數(shù)開(kāi)啟,當(dāng)同級(jí)節(jié)點(diǎn)數(shù)量達(dá)到geqo_threshold(默認(rèn)12)時(shí),PG將切換到遺傳搜索。遺傳搜索比動(dòng)態(tài)規(guī)劃的方法快得多。但并不能保證找到最佳計(jì)劃。該算法有許多可調(diào)整的選項(xiàng),這時(shí)另一篇文章主題。

選擇最佳計(jì)劃:最佳計(jì)劃的定義因預(yù)期用途而異。當(dāng)需要完整的輸出時(shí),計(jì)劃必須優(yōu)化與查詢匹配的所有行的檢索。另一方面,如果只想要前幾個(gè)匹配的行,則最佳計(jì)劃可能會(huì)完全不同。PG通過(guò)計(jì)算2個(gè)成本組件來(lái)解決這個(gè)問(wèn)題。他們顯示在“成本”一詞之后的查詢計(jì)劃輸出中:

Sort (cost=21.03..21.04 rows=1 width=128)

第一個(gè)組成部分:?jiǎn)?dòng)成本,是為節(jié)點(diǎn)執(zhí)行做準(zhǔn)備的成本;第2個(gè)組成部分,總成本:代表總節(jié)點(diǎn)執(zhí)行成本。

選擇計(jì)劃時(shí),計(jì)劃器首先要檢查是否使用cursor(可以通過(guò)DECLARE命令設(shè)置cursor或者在PL/pgSQL中明確聲明)。如果沒(méi)有,計(jì)劃器假設(shè)需要全部輸出并選擇總成本最低的計(jì)劃。否則,如果使用cursor,則規(guī)劃器會(huì)選擇一個(gè)規(guī)劃,以最佳方式檢索匹配行總數(shù)中等于cursor_tuple_fraction(默認(rèn)0.1)的行數(shù)。或者具體地說(shuō)最低的計(jì)劃:startup cost + cursor_tuple_fraction*(total cost- startup cost)。

成本計(jì)算過(guò)程。要估計(jì)計(jì)劃的成本,必須單獨(dú)估計(jì)其每個(gè)節(jié)點(diǎn)。節(jié)點(diǎn)成本取決于節(jié)點(diǎn)類(lèi)型(從表中讀取的成本遠(yuǎn)低于對(duì)表排序的成本)和處理的數(shù)據(jù)量(通常,數(shù)據(jù)越多,成本越高)。雖然節(jié)點(diǎn)類(lèi)型是立即知道的,但要評(píng)估數(shù)據(jù)量,我們首先需要估計(jì)節(jié)點(diǎn)的基數(shù)(輸入行的數(shù)量)和選擇性(剩余用于輸出的行的比例)。為此,我們需要數(shù)據(jù)統(tǒng)計(jì):表大小、跨列的數(shù)據(jù)分布。

因此優(yōu)化依賴(lài)于準(zhǔn)確的統(tǒng)計(jì)數(shù)據(jù),這些數(shù)據(jù)由自動(dòng)分析過(guò)程受繼并保持最新。

如果每個(gè)計(jì)劃節(jié)點(diǎn)的基數(shù)估計(jì)準(zhǔn)確,計(jì)算出的總成本通常會(huì)與實(shí)際成本相匹配。場(chǎng)景的計(jì)劃偏差通常是基數(shù)和選擇性估計(jì)不準(zhǔn)確的結(jié)果。這些錯(cuò)誤是由不準(zhǔn)確、過(guò)時(shí)或不可用的統(tǒng)計(jì)數(shù)據(jù)引起的,并在較小程度上是規(guī)劃期所基于的固有模型不完善。

基數(shù)估計(jì)。基數(shù)估計(jì)是遞歸執(zhí)行的。節(jié)點(diǎn)基數(shù)使用2個(gè)值計(jì)算:節(jié)點(diǎn)的字節(jié)的的基數(shù),或輸入行數(shù);節(jié)點(diǎn)的選擇性,或輸出行于輸入行的比例。基數(shù)是這2個(gè)值的成績(jī)。選擇性是一個(gè)介于0和1之間的數(shù)字。接近于零的選擇性值稱(chēng)為高選擇性,接近1的值稱(chēng)為低選擇性。這是因?yàn)楦哌x擇性會(huì)消除較高比例的行,而較低的選擇性值會(huì)降低閾值,因此丟棄的行數(shù)回更少。首先處理具有數(shù)據(jù)訪問(wèn)方法的葉節(jié)點(diǎn)。這就是表大小等統(tǒng)計(jì)信息的來(lái)源。應(yīng)用于表的條件的選擇性取決于條件類(lèi)型。在最簡(jiǎn)單的形式中,選擇性可以是一個(gè)常數(shù)值,但計(jì)劃著回嘗試使用所有可用信息來(lái)產(chǎn)生最準(zhǔn)確的估計(jì)。最簡(jiǎn)單條件的選擇性估計(jì)作為基礎(chǔ),使用不二運(yùn)算構(gòu)建的復(fù)雜條件可以使用以下簡(jiǎn)單公式進(jìn)一步計(jì)算:

selx and y = selx sely

selx or y = 1-(1-selx )(1-sely )=selx + sely - selx sely

在這些公式中,x和y認(rèn)為是獨(dú)立的。如果他們相關(guān),則使用這些公式,會(huì)使估計(jì)不太準(zhǔn)確。對(duì)于連接的基數(shù)估計(jì),計(jì)算2個(gè)值:笛卡爾積的基數(shù)(2個(gè)數(shù)據(jù)集的基數(shù)的乘積)和連接條件的選擇性,這又取決于條件類(lèi)型。其他節(jié)點(diǎn)類(lèi)型的基數(shù),例如排序或聚合節(jié)點(diǎn)也是類(lèi)似計(jì)算的。

請(qǐng)注意,較低節(jié)點(diǎn)中的基數(shù)計(jì)算錯(cuò)誤將向上傳播,導(dǎo)致成本估算不準(zhǔn)確,并最終導(dǎo)致次優(yōu)計(jì)劃。計(jì)劃器只有表的統(tǒng)計(jì)數(shù)據(jù),而不是連接結(jié)果的統(tǒng)計(jì)數(shù)據(jù),這使情況變得更糟。

代價(jià)估算。代價(jià)估算過(guò)程也是遞歸的。子樹(shù)的成本包括其子節(jié)點(diǎn)的成本加上父節(jié)點(diǎn)的成本。節(jié)點(diǎn)成本計(jì)算基于其執(zhí)行操作的數(shù)學(xué)模型。已經(jīng)計(jì)算的基數(shù)用于輸入。該過(guò)程計(jì)算啟動(dòng)成本和總成本。有些操作不需要任何準(zhǔn)備,可以立即開(kāi)始執(zhí)行。對(duì)于這些操作,啟動(dòng)成本是0.其他操作可能有先決標(biāo)記。例如排序節(jié)點(diǎn)通常需要來(lái)自其子節(jié)點(diǎn)的所有數(shù)據(jù)才能開(kāi)始操作。這些節(jié)點(diǎn)的啟動(dòng)成本不為0。即使下一個(gè)節(jié)點(diǎn)(或客戶端)只需要單行輸出,也必須計(jì)算此成本。

成本是計(jì)劃者的最佳估計(jì)。任何計(jì)劃錯(cuò)誤都會(huì)影響成本與實(shí)際執(zhí)行的相關(guān)程度。成本評(píng)估的注意目的是讓計(jì)劃者在相同條件下比較相同查詢的不同執(zhí)行計(jì)劃。在任何其他情況下,按成本比較查詢(更糟糕的是,不同的查詢)是沒(méi)有意義和錯(cuò)誤的。例如,考慮由于統(tǒng)計(jì)數(shù)據(jù)不準(zhǔn)確而被低估的成本。更新統(tǒng)計(jì)數(shù)據(jù)--成本可能會(huì)發(fā)生變化,但估算會(huì)變得更加準(zhǔn)確,計(jì)劃最終會(huì)得到改進(jìn)。

執(zhí)行

按照計(jì)劃執(zhí)行優(yōu)化后的查詢。在后端內(nèi)存中創(chuàng)建一個(gè)portal對(duì)象。Portal存儲(chǔ)著執(zhí)行查詢需要的狀態(tài)。這個(gè)狀態(tài)以樹(shù)的形式表示,其結(jié)構(gòu)與計(jì)劃樹(shù)相同。樹(shù)的節(jié)點(diǎn)作為裝配線,相互請(qǐng)求和傳遞行記錄:

poYBAGO2jdqAE7cvAAAkvUCc0Zo338.jpg

從root節(jié)點(diǎn)開(kāi)始執(zhí)行。Root節(jié)點(diǎn)(例子中的SORT節(jié)點(diǎn))向2個(gè)字節(jié)的請(qǐng)求數(shù)據(jù)。當(dāng)它接收到所有請(qǐng)求的數(shù)據(jù)時(shí)會(huì)執(zhí)行排序操作,然后將數(shù)據(jù)向上傳遞給客戶端。

一些節(jié)點(diǎn)(例如NESTLOOP節(jié)點(diǎn))連接來(lái)自不同來(lái)源的數(shù)據(jù)。該節(jié)點(diǎn)向2個(gè)字節(jié)的請(qǐng)求數(shù)據(jù)。在接收到與連接條件匹配的行后,節(jié)點(diǎn)立即將結(jié)果行傳遞給父節(jié)點(diǎn)(和排序不同,排序必須在處理他們之前接收所有行),然后該節(jié)點(diǎn)停止,知道其父節(jié)點(diǎn)請(qǐng)求另一行。因此,如果只需要部分結(jié)果(例如LIMIT設(shè)置),則操作不會(huì)完全執(zhí)行。

2個(gè)SEQSCAN葉節(jié)點(diǎn)是表掃描。根據(jù)父節(jié)點(diǎn)的請(qǐng)求,葉節(jié)點(diǎn)從表中讀取下一行并將其返回。這個(gè)節(jié)點(diǎn)和其他一些節(jié)點(diǎn)根本不存儲(chǔ)行,而只是交付并立即忘記他們。其他節(jié)點(diǎn)例如排序,可能需要一次存儲(chǔ)大量數(shù)據(jù)。為解決這個(gè)問(wèn)題,在后端內(nèi)存分配了一個(gè)work_mem內(nèi)存塊,默認(rèn)是保守的4MB限制;當(dāng)內(nèi)存用完時(shí),多余的數(shù)據(jù)會(huì)被發(fā)送到磁盤(pán)上的臨時(shí)文件中。

一個(gè)計(jì)劃可能包含多個(gè)具有存儲(chǔ)要求的節(jié)點(diǎn),因此他可能分配了幾塊內(nèi)存,每個(gè)塊大小為work_mem。查詢進(jìn)程可能占用的總內(nèi)存大小沒(méi)有限制。

擴(kuò)展查詢協(xié)議

使用簡(jiǎn)單的查詢協(xié)議,任何命令即使它一次又一次重復(fù)也會(huì)經(jīng)歷上述所有階段:解析、重寫(xiě)、規(guī)劃、執(zhí)行。但是沒(méi)有理由一遍又一遍地解析同一個(gè)查詢。如果他們盡在常量上有所不同,也沒(méi)有理由重新解析查詢:解析樹(shù)將是相同的。簡(jiǎn)單查詢協(xié)議的另一個(gè)煩惱是客戶端接收完整的輸出,而不管它可能有多長(zhǎng)。

這2個(gè)問(wèn)題都可以通過(guò)使用SQL命令來(lái)解決:為第一個(gè)問(wèn)題準(zhǔn)備一個(gè)查詢并執(zhí)行它,為第二個(gè)問(wèn)題聲明一個(gè)游標(biāo)并獲取所需行。但隨后客戶端將不得不處理命名新對(duì)象,而服務(wù)器將需要解析額外的命令。

擴(kuò)展查詢協(xié)議可以在協(xié)議命令級(jí)別對(duì)單獨(dú)的執(zhí)行階段進(jìn)行精確控制。

準(zhǔn)備

在準(zhǔn)備期間,查詢會(huì)像往常一樣被解析和重寫(xiě),但解析樹(shù)存儲(chǔ)在后端內(nèi)存中。PG沒(méi)有用于解析查詢的全局緩存。即使一個(gè)進(jìn)程之前已經(jīng)解析過(guò)查詢,其他進(jìn)程也必須再次解析它。然而,這中設(shè)計(jì)也有好處。在高負(fù)載下,全局內(nèi)存緩沖很容易因?yàn)殒i稱(chēng)為瓶頸。一個(gè)客戶端發(fā)送多個(gè)小命令可能會(huì)影響整個(gè)實(shí)例的性能。在PG中,查詢解析很便宜并與其他進(jìn)程隔離。

可以使用附加參數(shù)準(zhǔn)備查詢。下面是一個(gè)使用SQL命令的例子(同樣,這并不等同于協(xié)議命令級(jí)別的準(zhǔn)備,但最終的效果是一樣的):

PREPARE plane(text) ASSELECT * FROM aircrafts WHERE aircraft_code = $1;

本文的案例都使用demo數(shù)據(jù)庫(kù)“Airlines”。此視圖顯示所有命名的預(yù)準(zhǔn)備語(yǔ)句:

SELECT name, statement, parameter_types

FROM pg_prepared_statements gx

?[ RECORD 1 ]???+??????????????????????????????????????????????????

name | plane

statement | PREPARE plane(text) AS +

| SELECT * FROM aircrafts WHERE aircraft_code = $1;

parameter_types | {text}

該視圖沒(méi)有列出任何未命名的語(yǔ)句(使用擴(kuò)展協(xié)議或PL/pgSQL)。但它也沒(méi)有列出來(lái)其他會(huì)話的準(zhǔn)備好的語(yǔ)句:訪問(wèn)另一個(gè)會(huì)話的內(nèi)存是不可能的。

參數(shù)綁定

在執(zhí)行準(zhǔn)備好的查詢之前,會(huì)綁定當(dāng)前參數(shù)值。

EXECUTE plane('733');

aircraft_code | model | range

???????????????+???????????????+???????

733 | Boeing 737?300 | 4200(1 row)

與文字表達(dá)式的串聯(lián)相比,準(zhǔn)備好的語(yǔ)句的一個(gè)優(yōu)點(diǎn)是可以防止任何類(lèi)型的SQL注入。因?yàn)閰?shù)值不會(huì)影響已經(jīng)構(gòu)建的解析樹(shù)。在沒(méi)有準(zhǔn)備好的聲明的情況下達(dá)到相同的安全級(jí)別,將需要對(duì)來(lái)自不受信任來(lái)源的所有值進(jìn)行廣泛轉(zhuǎn)義。

規(guī)劃和執(zhí)行

執(zhí)行準(zhǔn)備好的語(yǔ)句時(shí),首先會(huì)考慮提供的參數(shù)來(lái)計(jì)劃其查詢,然后發(fā)送選擇的計(jì)劃以執(zhí)行。實(shí)際參數(shù)值對(duì)規(guī)劃者很重要,因?yàn)椴煌瑓?shù)集的最有規(guī)劃也可能不同。例如,在查找高級(jí)航班預(yù)訂時(shí),使用索引掃描(例如Index Scan字樣所示),因?yàn)橛?jì)劃者預(yù)計(jì)匹配的行不多:

CREATE INDEX ON bookings(total_amount);

EXPLAIN SELECT * FROM bookings WHERE total_amount > 1000000;

QUERY PLAN?????????????????????????????????????????????????????????????????????

Bitmap Heap Scan on bookings (cost=86.38..9227.74 rows=4380 wid...

Recheck Cond: (total_amount > '1000000'::numeric)

?> Bitmap Index Scan on bookings_total_amount_idx (cost=0.00....

Index Cond: (total_amount > '1000000'::numeric)

(4 rows)

然而,下一個(gè)條件完全符合所有預(yù)訂。索引掃描在這里沒(méi)用,進(jìn)行順序掃描Seq Scan:

EXPLAIN SELECT * FROM bookings WHERE total_amount > 100;

QUERY PLAN???????????????????????????????????????????????????????????????????

Seq Scan on bookings (cost=0.00..39835.88 rows=2111110 width=21)

Filter: (total_amount > '100'::numeric)

(2 rows)

在某些情況下,除了解析樹(shù)外,規(guī)劃器還會(huì)存儲(chǔ)查詢計(jì)劃,以避免再出現(xiàn)時(shí)再次規(guī)劃它。整個(gè)沒(méi)有參數(shù)值的計(jì)劃稱(chēng)為通用計(jì)劃,而不是使用給定參數(shù)值生成的自定義計(jì)劃。通用計(jì)劃的一個(gè)明顯用例是沒(méi)有參數(shù)的語(yǔ)句。

對(duì)于前4此運(yùn)行,帶有參數(shù)的預(yù)處理語(yǔ)句總是根據(jù)實(shí)際參數(shù)值進(jìn)行優(yōu)化。然后計(jì)算平均計(jì)劃成本。在第5次及以后,如果通用計(jì)劃平均比自定義計(jì)劃代價(jià)低,那么規(guī)劃器從那時(shí)起存儲(chǔ)和使用通用計(jì)劃,并進(jìn)行進(jìn)一步優(yōu)化。

plane準(zhǔn)備好的語(yǔ)句已經(jīng)執(zhí)行過(guò)一次,在接下來(lái)的2次執(zhí)行中,仍然使用自定義計(jì)劃,如查詢計(jì)劃中的參數(shù)值所示:

EXECUTE plane('763');

EXECUTE plane('773');

EXPLAIN EXECUTE plane('319');

QUERY PLAN??????????????????????????????????????????????????????????????????

Seq Scan on aircrafts_data ml (cost=0.00..1.39 rows=1 width=52)

Filter: ((aircraft_code)::text = '319'::text)

(2 rows)

執(zhí)行4次后,規(guī)劃器切換到通用規(guī)劃。在這種情況下,通用計(jì)劃與定制計(jì)劃相同,成本相同,因此更可取。現(xiàn)在EXPLAIN命令顯示參數(shù)編號(hào),而不是實(shí)際值:

EXECUTE plane('320');

EXPLAIN EXECUTE plane('321');
QUERY PLAN??????????????????????????????????????????????????????????????????

Seq Scan on aircrafts_data ml (cost=0.00..1.39 rows=1 width=52)

Filter: ((aircraft_code)::text = '$1'::text)

(2 rows)

不幸的是,只有前4個(gè)定制計(jì)劃比通用計(jì)劃更昂貴,而任何進(jìn)一步的定制計(jì)劃都會(huì)更便宜,但計(jì)劃者會(huì)完全忽略他們。另一個(gè)可能的不完善來(lái)源是計(jì)劃者比較成本估算,而不是要花費(fèi)的實(shí)際資源成本。

這就是為什么在版本12及更高版本中,如果用戶不喜歡自動(dòng)結(jié)果,他們可以強(qiáng)制系統(tǒng)使用通用計(jì)劃或自定義計(jì)劃。這是通過(guò)參數(shù)plan_cache_mode來(lái)完成:

SET plan_cache_mode = 'force_custom_plan';

EXPLAIN EXECUTE plane('CN1');
QUERY PLAN??????????????????????????????????????????????????????????????????

Seq Scan on aircrafts_data ml (cost=0.00..1.39 rows=1 width=52)

Filter: ((aircraft_code)::text = 'CN1'::text)

(2 rows)

14及更高版本中,pg_prepared_statements視圖還顯示計(jì)劃選擇統(tǒng)計(jì)信息:

SELECT name, generic_plans, custom_plans

FROM pg_prepared_statements;

name | generic_plans | custom_plans

???????+???????????????+??????????????

plane | 1 | 6

(1 row)

輸出檢索

擴(kuò)展查詢協(xié)議允許客戶端批量獲取輸出,一次多行,而不是一次全部獲取。借助游標(biāo)也可以實(shí)現(xiàn)相同目的,但成本更高,并且規(guī)劃器將優(yōu)化對(duì)第一個(gè)cursor_tuple_fraction行的檢索:

image.png

每當(dāng)查詢返回大量行并且客戶端都需要他們時(shí),一次檢索的行數(shù)對(duì)于整體數(shù)據(jù)傳輸速度至關(guān)重要。單批行越大,往返延遲損失的時(shí)間越少。然而,隨著批量大小的增加,節(jié)省的效率會(huì)下降。例如,從批量大小1切換到批量大小10將顯著增加時(shí)間節(jié)省。但從10切換到100幾乎沒(méi)有任何區(qū)別。

審核編輯 :李倩

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • SQL
    SQL
    +關(guān)注

    關(guān)注

    1

    文章

    789

    瀏覽量

    46700
  • 分析器
    +關(guān)注

    關(guān)注

    0

    文章

    93

    瀏覽量

    12917
  • 語(yǔ)法
    +關(guān)注

    關(guān)注

    0

    文章

    45

    瀏覽量

    10646
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    MySQL慢查詢分析與索引調(diào)優(yōu)全流程

    MySQL 性能問(wèn)題在生產(chǎn)環(huán)境的表現(xiàn)通常是漸進(jìn)式的:業(yè)務(wù)量增長(zhǎng)、數(shù)據(jù)量膨脹,某天突然發(fā)現(xiàn) P99 響應(yīng)時(shí)間從 50ms 漲到 2s。慢查詢是最常見(jiàn)的根因,而索引設(shè)計(jì)不合理又是慢查詢的主要來(lái)源。
    的頭像 發(fā)表于 03-06 15:56 ?62次閱讀

    變頻器故障查詢

    變頻器作為工業(yè)自動(dòng)化領(lǐng)域的關(guān)鍵設(shè)備,其穩(wěn)定運(yùn)行直接影響生產(chǎn)效率和設(shè)備安全。當(dāng)變頻器出現(xiàn)故障時(shí),快速準(zhǔn)確地查詢故障原因并采取相應(yīng)措施至關(guān)重要。本文將以西門(mén)子MM4系列變頻器為例,系統(tǒng)介紹常見(jiàn)故障
    的頭像 發(fā)表于 01-19 07:41 ?448次閱讀

    CW32 UART查詢方式接收數(shù)據(jù)編程的示例

    RXD 引腳配置成上拉輸入復(fù)用模式; 步驟 3:設(shè)置 UARTx_CR1.SYNC 為 0,配置 UARTx 為異步全雙工通信模式; 步驟 4:配置數(shù)據(jù)幀; 1.?起始位判定方式:配置
    發(fā)表于 12-16 08:19

    愛(ài)回收平臺(tái)價(jià)格查詢API接口詳解

    ,包括接口描述、參數(shù)說(shuō)明、請(qǐng)求示例、響應(yīng)格式和錯(cuò)誤處理。通過(guò)本文,您可以快速上手并集成該API到您的應(yīng)用1. API接口概述 該API是一個(gè)RESTful接口,用于查詢指定品牌和項(xiàng)目的價(jià)格信息。它基于HTTP GET方法,
    的頭像 發(fā)表于 11-19 14:57 ?574次閱讀
    愛(ài)回收平臺(tái)價(jià)格<b class='flag-5'>查詢</b>API接口詳解

    OBOO鷗柏丨立式廣告機(jī)機(jī)場(chǎng)交通軌道立體式商顯查詢設(shè)備新前沿

    ]的立式廣告機(jī)以其卓越的技術(shù)特點(diǎn)和多場(chǎng)景應(yīng)用優(yōu)勢(shì),成為機(jī)場(chǎng)立體式商顯查詢設(shè)備的首選。高效的信息傳遞與展示1.多功能顯示技術(shù)[OBOO鷗柏]立式廣告機(jī)采用先進(jìn)的工業(yè)顯
    的頭像 發(fā)表于 11-19 09:46 ?587次閱讀
    OBOO鷗柏丨立式廣告機(jī)機(jī)場(chǎng)交通軌道立體式商顯<b class='flag-5'>查詢</b>設(shè)備新前沿

    訂單實(shí)時(shí)狀態(tài)查詢接口技術(shù)實(shí)現(xiàn)

    、可靠的訂單實(shí)時(shí)狀態(tài)查詢接口,涵蓋接口設(shè)計(jì)、技術(shù)選型、代碼實(shí)現(xiàn)和性能優(yōu)化。我們將使用Python和Flask框架作為示例,確保內(nèi)容真實(shí)可靠,適合開(kāi)發(fā)人員參考。 1. 接口設(shè)計(jì)原則 訂單實(shí)時(shí)狀態(tài)查詢接口需要滿足以下要求: 實(shí)時(shí)性
    的頭像 發(fā)表于 10-21 17:58 ?731次閱讀
    訂單實(shí)時(shí)狀態(tài)<b class='flag-5'>查詢</b>接口技術(shù)實(shí)現(xiàn)

    商品類(lèi)目屬性查詢接口技術(shù)實(shí)現(xiàn)詳解

    ? ? 一、接口核心功能 該接口用于查詢電商系統(tǒng)商品類(lèi)目的屬性信息,支持: 按類(lèi)目ID查詢屬性集合 按屬性類(lèi)型過(guò)濾(關(guān)鍵屬性$K$、銷(xiāo)售屬性$S$、普通屬性$N$) 分頁(yè)返回屬性數(shù)據(jù) 多語(yǔ)言屬性名
    的頭像 發(fā)表于 10-11 15:43 ?461次閱讀
    商品類(lèi)目屬性<b class='flag-5'>查詢</b>接口技術(shù)實(shí)現(xiàn)詳解

    淘寶/天貓:使用物流查詢API實(shí)時(shí)顯示包裹位置,減少客服咨詢量

    ? ?引言 在電商平臺(tái)的日常運(yùn)營(yíng),物流咨詢往往占據(jù)客服工作量的40%以上。買(mǎi)家頻繁詢問(wèn)"我的包裹到哪里了?"不僅增加客服壓力,還影響用戶體驗(yàn)。本文將介紹如何通過(guò) 物流查詢API 實(shí)時(shí)顯示包裹位置
    的頭像 發(fā)表于 09-22 14:34 ?543次閱讀
    淘寶/天貓:使用物流<b class='flag-5'>查詢</b>API實(shí)時(shí)顯示包裹位置,減少客服咨詢量

    常用PromQL查詢案例總結(jié)

    在云原生時(shí)代,Prometheus已經(jīng)成為監(jiān)控領(lǐng)域的事實(shí)標(biāo)準(zhǔn)。作為一名資深運(yùn)維工程師,我見(jiàn)過(guò)太多團(tuán)隊(duì)在PromQL查詢上踩坑,也見(jiàn)過(guò)太多因?yàn)楸O(jiān)控不到位導(dǎo)致的生產(chǎn)事故。今天分享10個(gè)實(shí)戰(zhàn)中最常用的PromQL查詢案例,每一個(gè)都是血淚經(jīng)驗(yàn)的總結(jié)。
    的頭像 發(fā)表于 09-18 14:54 ?720次閱讀

    觸摸查詢軟件有哪些強(qiáng)大功能|高格欣科技查詢一體機(jī)終端

    領(lǐng)域,高格欣觸摸查詢機(jī)都能滿足您的多樣化需求。觸摸查詢軟件功能介紹:1、系統(tǒng)主要展示圖片、視頻、文檔,等資料,并實(shí)現(xiàn)對(duì)展示資料的多點(diǎn)操作(通過(guò)兩個(gè)手指以上進(jìn)行操作)
    的頭像 發(fā)表于 09-14 17:27 ?630次閱讀
    觸摸<b class='flag-5'>查詢</b>軟件有哪些強(qiáng)大功能|高格欣科技<b class='flag-5'>查詢</b>一體機(jī)終端

    淘寶/天貓:使用訂單查詢API實(shí)時(shí)追蹤包裹狀態(tài),自動(dòng)推送物流通知至用戶

    實(shí)現(xiàn)包裹狀態(tài)的實(shí)時(shí)監(jiān)控,并自動(dòng)推送物流更新通知給用戶,從而優(yōu)化服務(wù)流程。本文將逐步介紹如何利用淘寶/天貓的開(kāi)放平臺(tái)API實(shí)現(xiàn)這一功能,確保高效、可靠。 1. 理解訂單查詢API的基本原理 淘寶和天貓?zhí)峁┝艘幌盗虚_(kāi)放API(應(yīng)用程序
    的頭像 發(fā)表于 09-10 16:55 ?1281次閱讀
    淘寶/天貓:使用訂單<b class='flag-5'>查詢</b>API實(shí)時(shí)追蹤包裹狀態(tài),自動(dòng)推送物流通知至用戶

    如何查詢電能質(zhì)量在線監(jiān)測(cè)裝置的認(rèn)證標(biāo)準(zhǔn)?

    (以 CQC 認(rèn)證為例) 1. 全國(guó)標(biāo)準(zhǔn)信息公共服務(wù)平臺(tái)(官方權(quán)威渠道) 網(wǎng)址 :http://std.samr.gov.cn 操作步驟 : 進(jìn)入官網(wǎng)后,在搜索欄輸入標(biāo)準(zhǔn)編號(hào)(如 GB/T 19862-2005 )或關(guān)鍵詞(如 “電能質(zhì)量監(jiān)測(cè)設(shè)備”); 篩選結(jié)果的 “現(xiàn)
    的頭像 發(fā)表于 09-03 16:02 ?1025次閱讀
    如何<b class='flag-5'>查詢</b>電能質(zhì)量在線監(jiān)測(cè)裝置的認(rèn)證標(biāo)準(zhǔn)?

    MySQL慢查詢終極優(yōu)化指南

    作為一名在生產(chǎn)環(huán)境摸爬滾打多年的運(yùn)維工程師,我見(jiàn)過(guò)太多因?yàn)槁?b class='flag-5'>查詢導(dǎo)致的線上故障。今天分享一套經(jīng)過(guò)實(shí)戰(zhàn)檢驗(yàn)的MySQL慢查詢分析與索引優(yōu)化方法論,幫你徹底解決數(shù)據(jù)庫(kù)性能瓶頸。
    的頭像 發(fā)表于 08-13 15:55 ?849次閱讀

    產(chǎn)品詳情查詢API接口

    ? 在現(xiàn)代電子商務(wù)和軟件開(kāi)發(fā),產(chǎn)品詳情查詢API接口扮演著至關(guān)重要的角色。它允許開(kāi)發(fā)者通過(guò)編程方式從遠(yuǎn)程服務(wù)器獲取產(chǎn)品的詳細(xì)信息,如名稱(chēng)、價(jià)格、描述和庫(kù)存狀態(tài)等。這種接口通常基于RESTful架構(gòu)
    的頭像 發(fā)表于 07-24 14:39 ?581次閱讀
    產(chǎn)品詳情<b class='flag-5'>查詢</b>API接口

    媒體查詢詳解

    表。 表1 媒體邏輯操作符 類(lèi)型說(shuō)明and將多個(gè)媒體特征(Media Feature)以“與”的方式連接成一個(gè)媒體查詢,只有當(dāng)所有媒體特征都為true,查詢條件成立。另外,它還可以將媒體類(lèi)型和媒體功能
    發(fā)表于 06-25 08:26