簡體   English   中英

通過5個連接提高查詢性能

[英]Improve query performance with 5 join

使用本地Java程序,我可以訪問vps上的數據庫,該表所涉及的表平均約有1,500條記錄。

不幸的是,盡管記錄並不多,但提取時卻出現了大約10秒的性能問題。

查詢如下:

SELECT  DISTINCT P.advanced_stock_management,
        PA.id_product, PA.reference, PL.name,
        round(P.wholesale_price,2),
        round((P.price + P.price * 22 / 100), 2),
        round(SP.reduction,2),
        SA.quantity, PQ.is_true
    FROM  db.ps_product AS P
    INNER JOIN  db.ps_product_attribute AS PA
          ON P.id_product=PA.id_product
    INNER JOIN  db.ps_product_lang AS PL 
          ON PA.id_product=PL.id_product
    INNER JOIN  db.ps_stock_available AS SA
          ON SA.id_product_attribute=PA.id_product_attribute
    LEFT OUTER JOIN  db.ps_product_quantity_real AS PQ
          ON PA.id_product=PQ.id_product
         AND  PA.reference=PQ.reference
    LEFT OUTER JOIN  db.ps_specific_price AS SP
          ON PA.id_product=SP.id_product
    WHERE  P.active = 1;

如何改善查詢的結構並提高性能?

提前致謝。

您應該在以下列上使用適當的索引:

table_name (column_name)
ps_product (id_product)
ps_product_attribute (id_product)
ps_product_attribute (reference) 
ps_product_attribute (id_product_attribute)
ps_product_lang (id_product)
ps_stock_available (id_product_attribute)
ps_product_quantity_real (id_product)
ps_product_quantity_real (reference)
ps_specific_price (id_product)

通過使用適當的縮進重寫查詢:

SELECT DISTINCT 
    product.advanced_stock_management, 
    attribute.id_product, 
    attribute.reference, 
    lang.name, 
    round(product.wholesale_price,2), 
    round((product.price + product.price * 22 / 100),2), 
    round(price.reduction,2), 
    availablity.quantity, 
    quantity.is_true
FROM db.ps_product AS product
    INNER JOIN db.ps_product_attribute AS attribute 
        ON product.id_product = attribute.id_product
            INNER JOIN db.ps_product_lang AS lang 
                ON lang.id_product = attribute.id_product
            INNER JOIN db.ps_stock_available AS availablity 
                ON availablity.id_product_attribute = attribute.id_product_attribute
            LEFT OUTER JOIN db.ps_product_quantity_real AS quantity 
                ON attribute.id_product = quantity.id_product 
                AND attribute.reference = quantity.reference
            LEFT OUTER JOIN db.ps_specific_price AS price 
                ON price.id_product = attribute.id_product
WHERE product.active = 1;

我們可以看到中央表實際上是ps_product_attribute 讓我們將其作為查詢的開始:

SELECT DISTINCT 
    product.advanced_stock_management, 
    attribute.id_product, 
    attribute.reference, 
    lang.name, 
    round(product.wholesale_price,2), 
    round((product.price + product.price * 22 / 100),2), 
    round(price.reduction,2), 
    availablity.quantity, 
    quantity.is_true
FROM db.ps_product_attribute AS attribute
    INNER JOIN db.ps_product AS product
        ON attribute.id_product = product.id_product
    INNER JOIN db.ps_product_lang AS lang 
        ON attribute.id_product = lang.id_product 
    INNER JOIN db.ps_stock_available AS availablity 
        ON attribute.id_product_attribute = availablity.id_product_attribute
    LEFT OUTER JOIN db.ps_product_quantity_real AS quantity 
        ON attribute.id_product = quantity.id_product 
        AND attribute.reference = quantity.reference
    LEFT OUTER JOIN db.ps_specific_price AS price 
        ON attribute.id_product = price.id_product
WHERE product.active = 1;

現在查詢看起來非常好。
在此查詢的每個字段上都有索引嗎? 如果沒有,您應該!

ALTER TABLE `ps_product_attribute` ADD INDEX `id_product` (`id_product`)
ALTER TABLE `ps_product_attribute` ADD INDEX `reference` (`reference`)
ALTER TABLE `ps_product` ADD INDEX `id_product` (`id_product`)
ALTER TABLE `ps_product_lang` ADD INDEX `id_product` (`id_product`)
ALTER TABLE `ps_stock_available` ADD INDEX `id_product_attribute` (`id_product_attribute`)
ALTER TABLE `ps_product_quantity_real` ADD INDEX `id_product` (`id_product`)
ALTER TABLE `ps_product_quantity_real` ADD INDEX `reference` (`reference`)
ALTER TABLE `ps_specific_price` ADD INDEX `id_product` (`id_product`)

使用此數據庫大小,查詢應在1秒內運行。

你有兩個選擇

  • 在內存中預取1500條記錄,然后使用記錄匹配( 無數據庫 )進行聯接。 在從數據庫訪問記錄時,預取提供了速度並消除了網絡延遲,但是Ya記錄匹配將非常緩慢且令人厭煩。

  • 在本地集群中使用apache spark( bigdata joins )。 我已經在9ms內親自執行了100萬* 2次加入。 必須僅使用內存內RDD來實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM