<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 38.7\. 規則與觸發器的比較 許多用觸發器可以干的事情同樣也可以用PostgreSQL規則系統來實現。 目前不能用規則來實現的東西之一是某些約束,特別是外鍵。 可能在某字段的值沒有在另一個表里出現的情況下用一條有條件的規則把查詢重寫為`NOTHING`。 不過這樣做數據就會被不聲不響的扔掉,因而這也不是一個好主意。如果需要檢查有效的值, 而且如果是無效值出現時要生成一個錯誤信息,這種情況下要用觸發器來做。 在本節中,我們專注于使用規則更新視圖。本節中的所有更新規則的示例也可以使用在視圖上的 `INSTEAD OF`觸發器實現。編寫這樣的觸發器通常比編寫規則要容易, 尤其是需要復雜的邏輯執行更新時。 對于兩者都可用的情況,哪個更好取決于對數據庫的使用。觸發器為每個涉及到的行執行一次。 規則修改查詢或生成額外的查詢。所以如果在一個語句中涉及到多行, 一個生成額外查詢的規則通常可能會比一個對每一行都分別執行一次(而且要重新決定做什么很多次) 的觸發器快一些。不過,觸發器的方法從概念上要遠比規則的方法簡單,并且很容易讓新手可以做正確事情。 下面展示一個在同一個情況下選擇規則與觸發器的對比例子。例如這里有兩個表: ``` CREATE TABLE computer ( hostname text, -- 已索引 manufacturer text -- 已索引 ); CREATE TABLE software ( software text, -- 已索引 hostname text -- 已索引 ); ``` 兩個表都有好幾千行,并且`hostname`上的索引是唯一的。規則/觸發器應該實現這樣一個約束, 這個約束從`software`表中刪除引用已刪除計算機的行。觸發器可以用下面這條命令: ``` DELETE FROM software WHERE hostname = $1; ``` 因為觸發器是為從`computer`里面刪除的每一個獨立的行調用一次, 那么它可以準備并且保存這個命令的規劃,把`hostname`作為參數傳遞。 規則應該這樣寫: ``` CREATE RULE computer_del AS ON DELETE TO computer DO DELETE FROM software WHERE hostname = OLD.hostname; ``` 現在看看這兩種不同的刪除。在下面情況: ``` DELETE FROM computer WHERE hostname = 'mypc.local.net'; ``` 對表`computer`使用索引(快速)進行掃描并且由觸發器聲明的查詢也用索引進行掃描(同樣快速)。 規則里多出來的查詢是一個: ``` DELETE FROM software WHERE computer.hostname = 'mypc.local.net' AND software.hostname = computer.hostname; ``` 因為已經建立了合適的索引,規劃器將創建一個下面的規劃 ``` Nestloop -> Index Scan using comp_hostidx on computer -> Index Scan using soft_hostidx on software ``` 所以在規則和觸發器的實現之間沒有太多的速度差別。 下面的刪除希望刪掉所有 2000 個`hostname`以`old`開頭的計算機(記錄)。 有兩個可能的用于這個用途的查詢。一個是: ``` DELETE FROM computer WHERE hostname >= 'old' AND hostname < 'ole' ``` 規則增加的命令是: ``` DELETE FROM software WHERE computer.hostname >= 'old' AND computer.hostname < 'ole' AND software.hostname = computer.hostname; ``` 查詢的規劃將會是 ``` Hash Join -> Seq Scan on software -> Hash -> Index Scan using comp_hostidx on computer ``` 另一個可能的查詢是: ``` DELETE FROM computer WHERE hostname ~ '^old'; ``` 它由規則增加執行規劃是: ``` Nestloop -> Index Scan using comp_hostidx on computer -> Index Scan using soft_hostidx on software ``` 這表明,規劃器不能認識到表`computer`里的`hostname` 的條件在多個條件表達式以`AND`的方式組合在一起時同樣可以用于`software`上的索引掃描, 就像在用正則表達式的查詢里一樣。觸發器將在任何 2000 個要被刪除的舊計算機里被調用一次, 結果是對`computer`的一次索引掃描和對`software`的 2000 次索引掃描。 規則的實現將會使用兩個使用索引的命令來完成。所以`software` 表的實際大小決定了規則進行順序掃描后是否仍然更快。即使所有要使用的索引塊都很快在緩沖里出現, 執行 2000 個在 SPI 管理器上的查詢仍然要花不少時間。 我們要看的最后一個查詢是: ``` DELETE FROM computer WHERE manufacturer = 'bim'; ``` 同樣,這也會導致從`computer`表里刪除多行。 所以觸發器同樣會向執行器提交很多查詢。規則生成的命令將會是: ``` DELETE FROM software WHERE computer.manufacturer = 'bim' AND software.hostname = computer.hostname; ``` 但規則規劃又將是對兩個索引掃描的嵌套循環。不過使用了`computer`的另外一個索引: ``` Nestloop -> Index Scan using comp_manufidx on computer -> Index Scan using soft_hostidx on software ``` 在任何一種情況下,從規則系統出來的額外查詢都或多或少與查詢中涉及到的行數量相對獨立。 概括來說,規則只是在它們的動作生成了又大又爛的條件連接時才比觸發器有較大速度差異, 這時規劃器將失效。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看