【问题标题】:Laravel - What is the best approach to optimize update/insert queries with large data?Laravel - 使用大数据优化更新/插入查询的最佳方法是什么?
【发布时间】:2020-06-30 07:29:20
【问题描述】:

有超过 200 个用户登录。每个用户每 15 分钟在与父表 cars 相关的子表 car_prices 中插入/更新 1000 条记录。

CREATE TABLE `cars` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

CREATE TABLE `car_prices` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
    `car_id` bigint(20) unsigned NOT NULL,
    `price` decimal(8,2) NOT NULL,
    `created_at` timestamp NULL DEFAULT NULL,
    `updated_at` timestamp NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `car_prices_car_id_foreign` (`car_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

用户每 15 分钟执行一次此查询(例如):

INSERT INTO `car_prices` VALUES(NULL, 1, 3000, NOW(), NOW())
INSERT INTO `car_prices` VALUES(NULL, 2, 7000, NOW(), NOW())
INSERT INTO `car_prices` VALUES(NULL, 3, 5000, NOW(), NOW())
// ...and many other inserts approximately 1000

UPDATE `car_prices` SET `price` = 4000 WHERE `id` = 1;
UPDATE `car_prices` SET `price` = 8000 WHERE `id` = 2;
UPDATE `car_prices` SET `price` = 6000 WHERE `id` = 3;
// ...and many other updates approximately 1000

我该如何克服这个问题?有很多数据,更新/插入需要很长时间。我应该做一些 MySQL 可能具有的特殊功能吗?或者模式可能是错误的?或者我应该使用 Laravel 可能具有的一些功能?

【问题讨论】:

  • 你想克服什么问题?
  • @Strawberry 更新/插入需要很长时间。
  • 您应该分块插入数据(分块发送 SQL 命令,而不是一一发送)。我无法提供任何代码,因为我不知道您插入的完整上下文(数据来自何处、如何存储等)
  • 中间的 14 分钟用户在做什么?
  • @Strawberry 什么都没有。但我计算出用户几乎每 15 分钟插入/更新一次。

标签: mysql laravel query-optimization


【解决方案1】:

您可以使用块以更有效的方式执行此任务

查看我用于同步我的表产品的日常 cron 作业的这个示例

    DB::beginTransaction();

    try {

        $response = json_decode(file_get_contents('API_URL_GOES_HERE'), true);

        if(!empty($response['products'])) {
             

            $tempArr = [];

            foreach ($response['products'] as $product) {

                $tempArr[] = [
                    'name' => $product['name'],
                    'price' => $product['price'],
                    'category_id' => $product['category_id'],
                ];
            }

            Product::truncate();

            $insertData = collect($tempArr);

            $chunks = $insertData->chunk(500);

            foreach ($chunks as $chunk) {
                Product::insert($chunk->toArray());
            }

            DB::commit();

            dd($countProducts . ' Products imported successfully.');

        } else {

            dd('No products to import were found.');
        }

    } catch(\Exception $e) {

        DB::rollback();
        $this->info('');
        dump('Import failed : ' . $e->getMessage());
        dd('DB rolled back.');
    }

【讨论】:

    猜你喜欢
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    • 2021-01-28
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 1970-01-01
    相关资源
    最近更新 更多