私は10〜20秒かかるクエリがありますが、最適化できると確信しています。私はいくつかの助けと説明をして、同様のクエリに適用できるように説明したいと思います。あなたがそこに見るように、私が試したし、あまり成功に関与列を持ついくつかのインデックスを作成している 2つの結合とグループ句でmysqlクエリを最適化する
:
ここSELECT
`store_formats`.`Store Nbr`,
`store_formats`.`Store Name`,
`store_formats`.`Format Name`,
`eds_sales`.`Date`,
sum(`eds_sales`.`EPOS Sales`) AS Sales,
sum(`eds_sales`.`EPOS Quantity`) AS Quantity
FROM
`eds_sales`
INNER JOIN `item_codes` ON `eds_sales`.`Prime Item Nbr` = `item_codes`.`Customer Item`
INNER JOIN `store_formats` ON `eds_sales`.`Store Nbr` = `store_formats`.`Store Nbr`
WHERE
`eds_sales`.`Store Nbr` IN ($storenbr) AND
`eds_sales`.`Date` BETWEEN '$startdate' AND '$enddate' AND
`eds_sales`.`Client` = '$customer' AND
`eds_sales`.`Retailer` IN ($retailer) AND
`store_formats`.`Format Name` IN ($storeformat) AND
`item_codes`.`Item Number` IN ($products)
GROUP BY
`store_formats`.`Store Name`,
`store_formats`.`Store Nbr`,
`store_formats`.`Format Name`,
`eds_sales`.`Date`
がExplain出力です: はここに私のクエリです。主な遅延は私が考える一時的なテーブルへのコピーから発生します。
これらは関係する表のとおりです。
store_formats:
CREATE TABLE `store_formats` (
`id` int(12) NOT NULL,
`Store Nbr` smallint(5) UNSIGNED DEFAULT NULL,
`Store Name` varchar(27) DEFAULT NULL,
`City` varchar(19) DEFAULT NULL,
`Post Code` varchar(9) DEFAULT NULL,
`Region #` int(2) DEFAULT NULL,
`Region Name` varchar(10) DEFAULT NULL,
`Distr #` int(3) DEFAULT NULL,
`Dist Name` varchar(26) DEFAULT NULL,
`Square Footage` varchar(7) DEFAULT NULL,
`Format` int(1) DEFAULT NULL,
`Format Name` varchar(23) DEFAULT NULL,
`Store Type` varchar(20) DEFAULT NULL,
`TV Region` varchar(12) DEFAULT NULL,
`Pharmacy` varchar(3) DEFAULT NULL,
`Optician` varchar(3) DEFAULT NULL,
`Home Shopping` varchar(3) DEFAULT NULL,
`Retailer` varchar(15) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `store_formats`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `uniqness` (`Store Nbr`,`Store Name`,`Format`),
ADD KEY `Store Nbr_2` (`Store Nbr`,`Format Name`,`Store Name`);
eds_sales:
CREATE TABLE `eds_sales` (
`id` int(12) UNSIGNED NOT NULL,
`Prime Item Nbr` mediumint(7) NOT NULL,
`Prime Item Desc` varchar(255) NOT NULL,
`Prime Size Desc` varchar(255) NOT NULL,
`Variety` varchar(255) NOT NULL,
`WHPK Qty` int(5) NOT NULL,
`SUPPK Qty` int(5) NOT NULL,
`Depot Nbr` int(5) NOT NULL,
`Depot Name` varchar(50) NOT NULL,
`Store Nbr` smallint(5) UNSIGNED NOT NULL,
`Store Name` varchar(255) NOT NULL,
`EPOS Quantity` smallint(3) NOT NULL,
`EPOS Sales` decimal(13,2) NOT NULL,
`Date` date NOT NULL,
`Client` varchar(10) NOT NULL,
`Retailer` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `eds_sales`
ADD UNIQUE KEY `uniqness` (`Prime Item Nbr`,`Prime Item Desc`,`Prime Size Desc`,`Variety`,`WHPK Qty`,`SUPPK Qty`,`Depot Nbr`,`Depot Name`,`Store Nbr`,`Store Name`,`Date`,`Client`) USING BTREE,
ADD KEY `Store Nbr` (`Store Nbr`),
ADD KEY `Prime Item Nbr_2` (`Prime Item Nbr`,`Date`),
ADD KEY `id` (`id`) USING BTREE,
ADD KEY `Store Nbr_2` (`Prime Item Nbr`,`Store Nbr`,`Date`,`Client`,`Retailer`) USING BTREE,
ADD KEY `Client` (`Client`,`Store Nbr`,`Date`),
ADD KEY `Date` (`Date`,`Client`,`Retailer`);
item_codes:
CREATE TABLE `item_codes` (
`id` int(12) NOT NULL,
`Item Number` varchar(30) CHARACTER SET latin1 NOT NULL,
`Customer Item` mediumint(7) NOT NULL,
`Description` varchar(255) CHARACTER SET latin1 NOT NULL,
`Status` varchar(15) CHARACTER SET latin1 NOT NULL,
`Customer` varchar(30) CHARACTER SET latin1 NOT NULL,
`Sort Name` varchar(255) CHARACTER SET latin1 NOT NULL,
`EquidataCustomer` varchar(30) CHARACTER SET latin1 NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `item_codes`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `uniq` (`Item Number`,`Customer Item`,`Customer`,`EquidataCustomer`),
ADD KEY `Item Number_2` (`Item Number`,`Sort Name`,`EquidataCustomer`),
ADD KEY `Customer Item` (`Customer Item`,`Item Number`,`Sort Name`,`EquidataCustomer`),
ADD KEY `Customer Item_2` (`Customer Item`,`Item Number`,`EquidataCustomer`);
だから私の質問: ご覧のとおり、私は3つのテーブルに参加していますが、私は店舗形式で日付別に売上を探しています。私は別の種類の結合を試していました。たとえば、store_formatsを他のものに結びつけて、同じ結果をもたらすitem_codesとstore_formatsへの販売に参加する代わりに。私はまた、アプリケーション内の選択ボックスによって供給されるINを使用して、いくつかの変数の配列を渡しています。
- はテーブルごとに最適な索引が
- は、なぜ私は一時テーブルを得るのですか提案するこれらのテーブルを結合するための最良の方法?それはグループによるものなのでしょうか?回避策はありますか?
- 一時テーブルが必要な場合は、とにかくこの作成をスピードアップするにはどうすればよいですか? (私はすでに8枚のディスクを持つRAIDまだ遅くにデータフォルダを持っているもちろん
- 任意の提案の選択肢が
UPDATE歓迎されている:。コメントからいくつかの提案
UPDATEと私のテーブルを更新しました:修飾された私のmy.cnfとしてベローズ性能向上(私のRAMは8GB、2つのコアであり、/データ/ tmpが、8ドライブのRAIDにデータがある場合と同じである)
tmpdir = /dev/shm/:/data/tmp:/tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
expire_logs_days = 10
max_binlog_size = 100M
innodb_buffer_pool_size = 6G
innodb_buffer_pool_instances = 6
query_cache_type=1
この質問は、[DBA交換](https://dba.stackexchange.com/)でより専門的な注意が喚起される可能性があります。 –
質問を編集してテーブルのすべてのインデックスを表示できますか? –
質問にインデックスを追加 –