MySQL Оптимизация запросов с подзапросами и соединениями в большой базе данных - PullRequest
0 голосов
/ 27 апреля 2020

Я новичок здесь и уже искал решение для всего inte rnet. Если я что-то пропустил, пожалуйста, дайте мне знать!

Я использую 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) . Так что, вероятно, из-за этого шага.

Объяснение Выбор запроса

Заранее спасибо за вашу помощь. Если я могу предоставить какую-либо дополнительную информацию, пожалуйста, дайте мне знать.

--- EDIT ---

Итак, мне удалось изменить тип даты, и теперь я в состоянии выполнить запрос для ограничения в 50 строк . Но без ограничения я все еще получаю тайм-аут (время обработки более 7000).

Я также уменьшил VARCHAR (255) по индексам, где только мог. Не уверен, оказывает ли это влияние, но это уменьшило key_len (см. Последнее объяснение select). Вот новый код:

 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

Вот новый EXPLAIN select

Я очень благодарен за любую идею!

1 Ответ

0 голосов
/ 27 апреля 2020

Тебе не повезло в этом. НРАВИТСЯ фильтр% LIKE '% ...'. Есть вещи, которые вы можете сделать, например, создать динамический столбец c или не динамический столбец c, поддерживаемый триггером, который содержит обратную переменную tbl_patinfo.pub, а затем вместо tbl_patinfo.pub LIKE «% 2004» вы можете сказать tbl_patinfo.revpub LIKE «4002%»

...