私は注文を選択するためのクエリを持っており、各注文について、各製品のサマリ数量に含まれる製品のリストを取得する必要があります。クエリが遅い2つのテーブルフィールドでSELECT ... GROUP BY(MySQL/InnoDB)
現在、非常に遅いです(セットアップでは10秒です)。スピードアップする必要があります。
アップデート:MyISAMテーブルに切り替えることがオプションではありません、私はトランザクションを必要とする
クエリは、現在そのようなものです:
SELECT `Order`.*, `Product`.`id`, `Product`.`msrp`, SUM(`OrderItem`.`quantity`) AS sum
FROM `orders` AS `Order`
LEFT JOIN `order_items` AS `OrderItem` ON (`OrderItem`.`order_id` = `Order`.`id`)
LEFT JOIN `product_variations` AS `ProductVariation` ON (`OrderItem`.`product_variation_id` = `ProductVariation`.`id`)
LEFT JOIN `products` AS `Product` ON (`ProductVariation`.`product_id` = `Product`.`id`)
WHERE 1 = 1
GROUP BY `Order`.`id`, `Product`.`id`
ORDER BY `Order`.`created` DESC
LIMIT 20;
は説明:
をスキーマ(切り捨てられ、必須フィールドのみが残っています):
CREATE TABLE `orders` (
`id` int(11) NOT NULL auto_increment,
`created` timestamp NOT NULL default CURRENT_TIMESTAMP,
`customer_comments` text NOT NULL,
PRIMARY KEY (`id`),
KEY `created` (`created`),
KEY `id_created` (`id`,`created`),
) ENGINE=InnoDB
CREATE TABLE `order_items` (
`id` int(11) NOT NULL auto_increment,
`order_id` int(11) NOT NULL,
`product_variation_id` int(11) NOT NULL,
`type` enum('First','Second') default NULL,
`quantity` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `item_UNIQUE` (`order_id`,`product_variation_id`,`type`),
KEY `fk_order_items_product_variations1` (`product_variation_id`),
CONSTRAINT `fk_order_items_orders1` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_order_items_product_variations1` FOREIGN KEY (`product_variation_id`) REFERENCES `product_variations` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB
CREATE TABLE `product_variations` (
`id` int(11) NOT NULL auto_increment,
`product_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_product_variations_products1` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
) ENGINE=InnoDB
CREATE TABLE `products` (
`id` int(11) NOT NULL auto_increment,
`msrp` decimal(5,2) NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB
サーバはMySQL 5.0.77です。テーブルはInnoDBです。 orders
は約75kレコード、order_items
160kレコード、product_variations
140kレコード、product
- 300レコードです。
何か助けていただければ幸いです。
私は、最後の手段として事前計算合計および他の集計を開催しました。私の理解では、RDBMSが何かに優れているならば、それはフィルタリング、グループ化、集約です。私はもちろん、すべての集合体を事前に計算することができます。なぜRDBMSを使うのですか? – lxa
コンテキストについて - これはWebインターフェイスのページングクエリです。 (実際にはその一部です - 各注文のためにもう一度時間を要する必要があります - これを行う方法はまだわかりませんが、WITH ROLLUPはこのクエリでは機能しません)。 – lxa
ここでの問題はRDBMSではなく、テーブルエンジンです。集約が確かにボトルネックであるかどうかを確かめるためのテストとしてMyISAMに切り替えます。 InnoDBは集約時にすべての行を読み込みますが、MyISAMは集計しません。残念ながら、InnoDBのトランザクション/制約機能が必要な場合は、集約を自分でキャッシュする必要があります。 – Matt