首頁  >  文章  >  後端開發  >  基於TPC-C基準的Python ORM的性能測試詳解

基於TPC-C基準的Python ORM的性能測試詳解

coldplay.xixi
coldplay.xixi轉載
2020-07-28 16:57:283055瀏覽

基於TPC-C基準的Python ORM的性能測試詳解

##  當開發與資料庫需要一起使用的應用程式時,物件對應器(ORM)通常會用於Python程式中所使用的應用程式。 Python ORM的範例是SQLAlchemy,Peewee,Pony-ORM和Django。選擇ORM性能起著至關重要的作用。但是如何比較這些工具集?ORM性能基準提供了明確的度量,但仍有很大的改進空間。我研究並擴展了定性的ORM基準,以幫助有需要開發需要的東西。定性的Python ORM基準Tortoise ORM(連結到儲存庫)分析了11種SQL查詢的六個ORM的速度。

相關學習推薦:

python影片教學

#  通常,Tortoise基準可以評估各種ORM的查詢執行速度。但是,這種測試方法有一個缺陷:大多數ORM被選用於Web應用程式。在這種情況下,多個使用者經常將所有形式的查詢傳送到資料庫。因為在這種情況下沒有評估的基準測試工具能夠評估Python ORM的效能,所以我決定編寫自己的PonyORM和SQLAlchemy進行比較。作為基礎,我採用了TPC-C基準。

  自1988年以來,TPC一直在資料處理領域開發測試。它們早已成為行業標準,幾乎所有設備供應商都在各種硬體和軟體樣本上使用它們。這些測試的主要特徵是它們專注於在盡可能接近真實條件的巨大負載下進行測試。

  TPC-C模擬倉庫網路。它包括五個同時執行的各種類型和複雜性的事務的組合。此測試的目的是評估多個虛擬使用者同時存取資料庫時事務處理的速度。

  我決定使用適合此任務的TPC-C測試方法測試兩個Python ORM(SQLALchemy和PonyORM)。此測試的目的是評估多個虛擬使用者同時存取資料庫時事務處理的速度。

  測試說明

  第一步是建立並填入倉庫網路的資料庫。

  此資料庫包含八個關係:

  1. 倉庫

  2. 區

##  3. 訂購

  4. 訂單行

  5. 股票

  6.項目

  7.顧客

  8.歷史

  Pony和SQLAlchemy的資料庫是相同的。僅索引主鍵和外鍵。小A會自動建立這些索引。在SQLAlchemy中,我手動建立了它。

  在測試過程中,幾種虛擬使用者將不同類型的交易傳送到資料庫。每個事務包含幾個請求。總共有五種類型的交易以不同的發生機率提交處理:

  交易:

  1. 新訂單-45%

  2.付款-43%

  3. order_status-4%

  4. 交付-4%

  5. 股票水平-4%

  發生交易的可能性與原始TPC- C測試中的相同。

  但是,請記住,由於技術上的限制以及我想測試以下處理器的性能,因此在具有64 GB以上RAM(需要大量處理器和巨大磁碟空間)的伺服器上進行了原始TPC-C測試。 ORM而不是硬體抵抗巨大負載的能力,因此此測試有所簡化。

  與TPC-C測試的主要差異如下:

  主要差異:

  1. 此測試運行的虛擬使用者少於原始測試

#  22 . 我的測試的表格條目較少。例如:原始測試中「庫存」關係中的條目數是使用公式100,000 * W計算的,其中W是倉庫數。在此測試中為100 *W。

  3. 在TPC-C中,某些交易具有從資料庫查詢資料的多個選項。例如,在支付交易中,有一種可能性,將透過ID從資料庫中請求客戶,而另一種則是由姓和名。目前,我的測試僅按ID撥打電話。

  4. 我的測試資料庫比TPC-C少一個表格。在TPC-C測試中,建立訂單後,會將其加入Order表和NewOrder表中。訂單交付後,便從NewOrder表中刪除。每分鐘應用大量事務時,這可以加快工作速度;但是由於我訪問資料庫的用戶較少,所以這是不必要的。相反,在Order表中,我添加了bool屬性“ is_o_delivered”,該屬性將為False,直到交付訂單為止。

  接下來,我將簡單描述每個事務的作用。

  交易次數

  新指令

  1. 將兩個參數傳遞給交易:倉庫ID和客戶ID

#  2. 使用傳遞的ID從資料庫中選擇倉庫和客戶

  3. 從資料庫中隨機選擇一個倉庫區域

  4. 產生指示訂單行數的隨機數。

  5. 建立一個Order物件

  6. 循環建立OrderLine物件。在循環的每個迭代中,從項目表中選擇一個隨機項目

  7. 更改訂單中每個項目的庫存

  付款

  1. 將兩個參數傳遞給交易:倉庫ID和客戶ID

  2. 透過傳遞的ID從資料庫中選擇倉庫和客戶

  3. 從資料庫中隨機選擇一個倉庫區域

  4. 產生一個指示付款金額的隨機數字

  5. 按付款金額增加倉庫和區域的餘額

  6. 客戶餘額減少付款金額

#  7.遞增客戶付款櫃檯

  8.客戶付款金額的總和增加

#  9.建立歷史記錄物件

  訂單狀態

  1.的參數

  2. 透過ID和該客戶的最後訂單選擇客戶

  3. 從訂單中取得訂單狀態和訂單行。

  交貨

  1. 傳遞倉庫ID作為交易參數

  2. 從資料庫中選擇倉庫及其所有區域

##  3. 為每個地區選擇最舊的未交付訂單。

  4. 對於每個將交貨狀態更改為True的訂單

  5. 對於每個訂單數量遞增的客戶

  庫存水準

# 1. 傳遞倉庫ID作為交易參數

  2. 透過ID從資料庫中選擇倉庫

  3. 選擇該倉庫的最後20個訂單

  4. 對於訂單中的每個項目,評估項目的庫存水準

  檢測結果

  有兩個ORM參與測試:

  1. SQLAlchemy(圖形上的藍線)

  2. PonyORM(圖形上的橘色線)

  以下是透過2個平行程序存取資料庫執行測試10分鐘的結果。使用「多重處理」模組啟動流程。

  X軸-時間(以分鐘為單位)

  Y軸-已完成的交易數

  作為DBMS,我使用PostgreSQL

  所有交易

  首先,按照TPC-C測試中的預期,我對所有五個事務進行了測試。這項測試的結果是,小A的速度大約是以前的兩倍。

  平均速度:

  · 小A-2543筆交易/分鐘

  · SQLAlchemy-1353.4事務/分鐘

  · SQLAlchemy-1353.4事務/分鐘

  ·##]  之後,我決定分別評估五筆之後,我決定分別評估五筆交易中ORM的效能。以下是每筆交易的結果。

  新指令

  平均速度:

  · 小A-3349.2交易/分鐘

  · SQLAlchemy-1415.3/分鐘

  · SQLAlchemy-1415.3/分鐘

#/分鐘

##白交易付款

  平均速度:

  · 小A-7175.3事務/分鐘

  · SQLAlchemy-4110.6事務/分鐘

  · SQLAlchemy-4110.6事務/分鐘

 訂單狀態

 訂單狀態

」訂單狀態#  平均速度:

  · 小A-16645.6交易/分鐘

  · SQLAlchemy-4820.8事務/分鐘

  交貨

  平均速度:

  · SQLAlchemy-716.9事務/分鐘

  · 小A-323.5交易/分鐘

  庫存水平

  平均速度:

  · 小A-677.3交易/分鐘

  · SQLAlchemy-167.9事務/分鐘

  測試結果分析

  收到結果後,我分析了為什麼會這樣,並得出以下結論:

  在5分之4的事務中,PonyORM的速度更快,因為在產生SQL程式碼時,PonyORM會記得將Python表達式轉換為SQL的結果。因此,Pony不會在重複查詢時再次轉換該表達式,而SQLAlchemy在每次需要執行查詢時都會被強制產生SQL程式碼。

  Pony中此類查詢的範例:

stocks = select(stock for stock in Stock
  if stock.warehouse == whouse
  and stock.item in items).order_by(Stock.id).for_update()

  產生的SQL: 

 SELECT “stock”.”id”, “stock”.”warehouse”, “stock”.”item”,
  “stock”.”quantity”, “stock”.”ytd”, “stock”.”order_cnt”,
  “stock”.”remote_cnt”, “stock”.”data”FROM “stock” “stock”WHERE “stock”.”warehouse” = %(p1)s
  AND “stock”.”item” IN (%(p2)s, %(p3)s)ORDER BY “stock”.”id”FOR UPDATE
  {‘p1’:7, ‘p2’:7, ‘p3’:37}
  SQLAlchemy:
  stocks = session.query(Stock).filter(
  Stock.warehouse == whouse, Stock.item.in_(
  items)).order_by(text(“id”)).with_for_update()

  生成的SQL: 

SELECT stock.id AS stock_id, stock.warehouse_id AS stock_warehouse_id,
  stock.item_id AS stock_item_id, stock.quantity AS stock_quantity,
  stock.ytd AS stock_ytd, stock.order_cnt AS stock_order_cnt,
  stock.remote_cnt AS stock_remote_cnt, stock.data AS stock_dataFROM stockWHERE stock.warehouse_id = %(warehouse_id_1)s AND stock.item_id IN
  (%(item_id_1)s, %(item_id_2)s) ORDER BY id FOR UPDATE
  {‘warehouse_id_1’: 7, ‘item_id_1’: 53, ‘item_id_2’: 54}

   生成的SQL: ###
INFO:www.zpedu.com/sqlalchemy.engine.base.Engine:UPDATE order_line SET delivery_d=%
  (delivery_d)s WHERE order_line.id = %(order_line_id)s
  INFO:sqlalchemy.engine.base.Engine:(
  {‘delivery_d’: datetime.datetime(2020, 4, 6, 14, 33, 6, 922281),
  ‘order_line_id’: 316},
  {‘delivery_d’: datetime.datetime(2020, 4, 6, 14, 33, 6, 922272),
  ‘order_line_id’: 317},
  {‘delivery_d’: datetime.datetime(2020, 4, 6, 14, 33, 6, 922261))
###  快速執行交付類型事務,因為它可以將應用於不同物件的多個UPDATE操作組合到一個命令中。 ######  例: ###rrreee###  在這種情況下,小A會為每個更新發送單獨的查詢。 ######  結論######  根據測試的結果,我可以說Pony從資料庫中選擇的速度更快。另一方面,在某些情況下,SQLAlchemy可以以更高的速度產生Update類型的查詢。 ###

以上是基於TPC-C基準的Python ORM的性能測試詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:learnku.com。如有侵權,請聯絡admin@php.cn刪除