Оптимизация запроса php на удаление

139
17 августа 2021, 15:10

Всем привет, есть такой запрос на удаление, сейчас он нагружает проц. на 100%. Его реально оптимизировать?

foreach ($ids as $pid) {

            $composes = Product::getComposes($pid, $idUser);
            if ($sql->exec('select `id`,`file` from `' . TABLE_PRODUCTS_IMAGES . '` where `id_user` = "' . $sql->quotes($idUser) . '" and `id_product` = "' . $sql->quotes($pid) . '"')) {
                while ($image = $sql->getAscRow()) {
                    if (Files::delete(USERS_DIR . '/' . $sql->quotes($idUser) . '/products/images/' . $image['file'])) {
                        $sqlDelete->exec('delete from `' . TABLE_PRODUCTS_IMAGES . '` where `id_user` = ' . $sql->quotes($idUser) . ' and `id_product` = ' . $sql->quotes($pid) . ' and  `id` = ' . $sql->quotes($image['id']));
                        Files::delete(USERS_DIR . '/' . $sql->quotes($idUser) . '/products/images/preview/' . $image['file']);
                    }
                }
            }
            $sqlDelete->exec('delete from `' . TABLE_PRODUCTS_SEO . '` where `id_user` = ' . $sql->quotes($idUser) . ' and `id_product` = ' . $sql->quotes($pid));
            $sqlDelete->exec('delete from `' . TABLE_PRODUCTS_SPECIFICATIONS . '` where `id_user` = ' . $sql->quotes($idUser) . ' and `id_product` = ' . $sql->quotes($pid));
            $sqlDelete->exec('delete from `' . TABLE_PRODUCTS_SET . '` where `id_user` = ' . $sql->quotes($idUser) . ' and `id_product` = ' . $sql->quotes($pid));
            $sqlDelete->exec('delete from `' . TABLE_PRODUCTS . '` where `id_user` = ' . $sql->quotes($idUser) . ' and `id` = ' . $sql->quotes($pid));
            if ($sql->exec('select * from `' . TABLE_PRODUCTS_SET . '` where `id_user` = "' . $sql->quotes($idUser) . '" and `set` like "%' . $sql->quotes($pid) . '%"')) {
                while ($result = $sql->getAscRow()) {
                    $set = (!empty($result['set'])) ? json_decode($result['set'], true) : [];
                    unset($set[$sql->quotes($pid)]);
                    $sqlDelete->exec('delete from `' . TABLE_PRODUCTS_SET . '` where `id_product`= "' . $sql->quotes($result['id_product']) . '" and `id_user` = "' . $sql->quotes($idUser) . '"');
                }
            }
            if (!empty($composes)) {
                $main = array_shift($composes);
                $sql->exec('update `' . TABLE_PRODUCTS . '` set `id_compose` = null where `id`= "' . $main['id'] . '" and `id_user` = "' . $sql->quotes($idUser) . '"');
                foreach ($composes as $pc) {
                    $sql->exec('update `' . TABLE_PRODUCTS . '` set `id_compose` = "' . $main['id'] . '" where `id`= "' . $pc['id'] . '" and `id_user` = "' . $sql->quotes($idUser) . '"');
                    Product::setClearCacheByDependence($pc['id'], $idUser);
                }
                //return json_encode(['newcompose' => $main['id']]);
            } else {
                //return json_encode([]);
            }
        }
    }
Answer 1

Вы можете указать несколько таблиц в инструкции DELETE для удаления строк из одной или нескольких таблиц в зависимости от конкретного условия в предложении WHERE..... В предложении table_references перечислены таблицы, участвующие в объединении.

DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;

Как раз для вашего случая, где только таблицы разные, а остальное одинаковое.

По 8.0 версии MySQL:

Полезная ссылка https://dev.mysql.com/doc/refman/8.0/en/delete.html

Multiple-Table Syntax

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    tbl_name[.*] [, tbl_name[.*]] ...
    FROM table_references
    [WHERE where_condition]
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    FROM tbl_name[.*] [, tbl_name[.*]] ...
    USING table_references
    [WHERE where_condition]

+Для дальнейшей оптимизации DELETE:

8.2.5.3 Optimizing DELETE Statements https://dev.mysql.com/doc/refman/8.0/en/delete-optimization.html

...Чтобы быстрее удалять строки, вы можете увеличить размер кэша ключей, увеличив системную переменную key_buffer_size. См. Раздел 5.1.1, «Настройка сервера».

READ ALSO
Как составить sql запрос c объединением?

Как составить sql запрос c объединением?

в общем, есть проблемка, нужно объединить две таблицы в sql запросе

103
Java annotations for field

Java annotations for field

Мне нужно аннотировать поле, которое используется в разных классахКак можно аннотировать его так, чтобы в одном классе возвращалось его...

196