簡體   English   中英

MySQL 在大型數據庫上使用子查詢和聯接進行查詢優化

[英]MySQL Query Optimization with subqueries and JOINs on large database

我是新來的,已經在整個互聯網上搜索了解決方案。 如果我錯過了什么,請告訴我!

我使用具有數百萬個條目的 MySQL MariaDB。 我的查詢導致超時。 即使增加超時也無濟於事。 查詢的目標是每年檢索相關條目。 我的查詢必須加入總共 5 個表。 (不幸的是,數據庫的結構是預定義的,我幾乎無法更改)。

您可以在下面找到受影響的查詢。 日期存儲為 varchar ,這就是我使用LIKE %運算符的原因。 不幸的是,我沒有更改它的權限。

    SELECT
    spCit.spPN,
    spCit.ipc1,
    spCit.ipc2,
    tbl_patinfo.pn
FROM
    tbl_patinfo
INNER JOIN(
    SELECT
        spIPC.spPN,
        spIPC.ipc1,
        spIPC.ipc2,
        tbl_patcit.pc_pn AS spDocNr
    FROM
        tbl_patcit
    INNER JOIN(
        SELECT DISTINCT
            tbl_ipc.pn AS spPN,
            tbl_ipc.value AS ipc1,
            tbl_ipc.main_cl AS ipc2
        FROM
            tbl_ipc
        RIGHT JOIN(
            SELECT
                tbl_sp.sp_CompanyAlias,
                OrgName,
                infoPN
            FROM
                tbl_sp
            INNER JOIN(
                SELECT DISTINCT
                    tbl_patinfo.pn AS infoPN,
                    tbl_adr.orgname AS OrgName
                FROM
                    tbl_patinfo
                LEFT JOIN tbl_adr ON tbl_patinfo.pn = tbl_adr.pn
                WHERE
                    tbl_patinfo.pub LIKE "%2004"
            ) AS PatPerYear
        ON
            tbl_sp.sp_CompanyAlias = PatPerYear.Orgname
        ) AS spPatents
    ON
        tbl_ipc.pn = spPatents.infoPN
    ) AS spIPC
ON
    tbl_patcit.pn = spIPC.spPN
) AS spCit
ON
    tbl_patinfo.docnr = spCit.spDocNr

注意:如果我不進行最后一次 JOIN ( tbl_patinfo.docnr = spCit.spDocNr) ,則整個查詢都有效。 所以很可能是因為這一步。

解釋查詢的Select

在此先感謝您的幫助。 如果我可以提供任何進一步的信息,請告訴我。

- -編輯 - -

所以我設法更改了日期類型,現在我能夠執行50 行限制的查詢。 但是沒有限制,我仍然會超時(超過 7000 秒的處理時間)。

我還盡可能減少了索引上的 VARCHAR(255)。 不確定這是否有影響,但這減少了 key_len (請參閱最新的解釋選擇)。 這是新代碼:

 SELECT
        spCit.spPN,
        spCit.ipc1,
        spCit.ipc2,
        tbl_patinfo.pn
    FROM
        tbl_patinfo
    INNER JOIN(
        SELECT
            spIPC.spPN,
            spIPC.ipc1,
            spIPC.ipc2,
            tbl_patcit.pc_pn AS spDocNr
        FROM
            tbl_patcit
        INNER JOIN(
            SELECT DISTINCT
                tbl_ipc.pn AS spPN,
                tbl_ipc.value AS ipc1,
                tbl_ipc.main_cl AS ipc2
            FROM
                tbl_ipc
            RIGHT JOIN(
                SELECT
                    tbl_sp.sp_CompanyAlias,
                    OrgName,
                    infoPN
                FROM
                    tbl_sp
                INNER JOIN(
                    SELECT DISTINCT
                        tbl_patinfo.pn AS infoPN,
                        tbl_adr.orgname AS OrgName
                    FROM
                        tbl_patinfo
                    LEFT JOIN tbl_adr ON tbl_patinfo.pn = tbl_adr.pn
                    WHERE
                        YEAR(tbl_patinfo.pub) = 2004
                ) AS PatPerYear
            ON
                tbl_sp.sp_CompanyAlias = PatPerYear.Orgname
            ) AS spPatents
        ON
            tbl_ipc.pn = spPatents.infoPN
        ) AS spIPC
     ON
        tbl_patcit.pn = spIPC.spPN
    ) AS spCit
    ON
        tbl_patinfo.docnr = spCit.spDocNr

這是新的解釋 select

我非常感謝任何想法!

你在那個方面不走運。 LIKE '%...' 過濾器是不可索引的。 你可以做一些事情,例如創建一個動態列,或由觸發器維護的非動態列,其中包含 tbl_patinfo.pub 的反向,然后你可以代替 tbl_patinfo.pub LIKE '%2004'說 tbl_patinfo.revpub LIKE '4002%'

暫無
暫無

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

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