Какие показатели для улучшения производительности JOIN и GROUP BY - PullRequest
0 голосов
/ 25 октября 2018

Я настроил несколько таблиц и выполнил запрос.Однако, в моем объяснении будет показано, что результаты SQL генерируются во временной таблице (я предполагаю, что это из-за GROUP BY)

Я добавил несколько индексов для ускорения запроса, но мне интересно, есть ли способпрекратить использование временной таблицы и, если есть какой-либо другой способ ускорить мой запрос с помощью индексов?

CartData

CREATE TABLE `cartdata` (
    `IDCartData` INT(11) NOT NULL AUTO_INCREMENT,
    `CartOrderref` VARCHAR(25) NOT NULL DEFAULT '',
    `UserID` INT(11) NOT NULL DEFAULT '0',
    `LastUpdate` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE 
    CURRENT_TIMESTAMP,
    `ManualContactName` VARCHAR(100) NOT NULL DEFAULT '',
    `ManualOrderConfirmationEmail` VARCHAR(100) NOT NULL DEFAULT '',
    PRIMARY KEY (`IDCartData`),
    INDEX `CartOrderref` (`CartOrderref`)
)

CartSplitData

    CREATE TABLE `cartsplitdata` (
        `IDCartSupplierData` INT(11) NOT NULL AUTO_INCREMENT,
        `IDCartData` INT(11) NOT NULL DEFAULT '0',
        `supplierid` INT(11) NOT NULL DEFAULT '0',
        `DeliveryDate` DATE NOT NULL DEFAULT '2000-01-01',
        `AccountNumber` VARCHAR(50) NOT NULL DEFAULT '',
        `ManualOrderref` VARCHAR(50) NOT NULL DEFAULT '',
        `lastupdate` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (`IDCartSupplierData`),
        INDEX `cartdatasupplierid` (`IDCartData`, `supplierid`)
    )

Мой пример запроса

        EXPLAIN SELECT max(CartData.idCartDATA) AS idCartDATA , CartData.*, CartSplitData.*
        FROM CartData
        JOIN CartSplitData ON CartSplitData.IDCartDATA = CartDATA.IDCartData
        WHERE  CartData.CartOrderref = 'XXXXXXXXX'
        group by CartSplitData.SUPPLIERID

Объяснение результатов запроса Explain of query results

1 Ответ

0 голосов
/ 25 октября 2018

Pro tip Избегайте SELECT * или SELECT table.* в чувствительных к производительности запросах.Вместо этого выберите по имени столбцы, которые вам действительно нужно использовать

Pro tip MySQL имеет пресловутое нестандартное расширение для GROUP BY, которое вы используете, и, возможно, злоупотребляете.Прочитай это.https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html Если вы следовали первому профессиональному совету, последовать за вторым было бы намного легче.

Профессиональный совет Избегайте "вбрасывания" большого количества отдельных столбцов индексов в надежде на ускорениеваши запросы.Вместо этого создайте индексы, часто составные индексы, соответствующие потребностям вашего фактического запроса.Прочитайте это https://use -the-index-luke.com .

Pro tip Using temporary; using filesort, появляющийся в выводе EXPLAIN, не обязательно плох.Это просто означает, что механизм запросов должен кэшировать частичный набор результатов перед его возвратом.temporary - это не фактическая таблица, это структура ОЗУ.Если он настолько большой, что забивает ОЗУ, MySQL выливает его на диск.Но это не так.

С учетом всего сказанного, давайте проведем рефакторинг вашего запроса.Я предполагаю, что вы хотите получить строки с наибольшим значением idCartDATA для каждого CartSplitData.SUPPLIERID.

Итак, давайте запишем это как подзапрос.

                  SELECT max(IDCartDATA) AS IDCartDATA, SUPPLIERID
                    FROM CartSplitData
                   GROUP BY SUPPLIERID

Этот запрос может быть ускорендраматически, поместив составной индекс в CartSplitData: (SUPPLIERID, IDCartDATA).

Далее, давайте перепишем ваш основной запрос, чтобы найти строки, соответствующие идентификаторам в этом подзапросе.

SELECT CartData.*             /* * hammers performance */
       CartSplitData.*        /* * hammers performance */
  FROM CartData
  JOIN CartSplitData ON CartSplitData.IDCartDATA = CartDATA.IDCartData
  JOIN (
                  SELECT max(IDCartDATA) AS IDCartDATA, SUPPLIERID
                    FROM CartSplitData
                   GROUP BY SUPPLIERID
       )x ON x.SUPPLIERID = CartSplitData.SUPPLIERID
         AND x.IDCartData = CartSplitData.IDCartData
 WHERE CartData.CartOrderref = 'XXXXXXXXX'

Ваш индексCartData.CartOrderref поможет этот внешний запрос, как и составной индекс, созданный ^^^.

...