製品に関する情報を含む次の表を作成しました。
CREATE TABLE `AllProducts` (
`insertionTime` datetime NOT NULL,
`shop` varchar(40) CHARACTER SET utf8 NOT NULL,
`name` varchar(100) CHARACTER SET utf8 NOT NULL,
`category` varchar(40) CHARACTER SET utf8 NOT NULL,
`description` text CHARACTER SET utf8 NOT NULL,
`price` decimal(10,2) NOT NULL,
`url` varchar(350) COLLATE latin1_german1_ci NOT NULL,
`image` varchar(450) CHARACTER SET utf8 NOT NULL,
`fromPrice` text CHARACTER SET utf8 NOT NULL,
`deliveryCosts` decimal(10,2) NOT NULL,
`stock` text CHARACTER SET utf8 NOT NULL,
`deliveryTime` varchar(80) CHARACTER SET utf8 NOT NULL,
`ean` varchar(32) CHARACTER SET utf8 NOT NULL,
`color` varchar(40) CHARACTER SET utf8 NOT NULL,
`size` varchar(40) CHARACTER SET utf8 NOT NULL,
`brand` varchar(40) CHARACTER SET utf8 NOT NULL,
KEY `category` (`category`),
KEY `nameShopInsertiontime` (`name`,`shop`,`insertionTime`),
KEY `name` (`name`),
KEY `catNameShopInsert` (`category`,`name`,`shop`,`insertionTime`),
KEY `eanName` (`ean`,`name`),
KEY `eanInsertionTime` (`ean`,`insertionTime`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german1_c
そのテーブルからすべての固有の製品を選択するビュー (「プロトタイプ製品」ビュー) を作成したいと考えています。テーブル内の一部の製品には EAN 番号がありますが、すべてではありません。利用可能な EAN 番号があれば、それを productId として使用したいと考えています。利用できない場合は、名前を (小文字で) ハッシュし、それを productId として使用します。
上記の状況を区別するためにユニオン all を使用する次のビューを作成しました。動作しますが、完了するまでに 4.3 秒かかります (200.000 行で)。これは遅すぎます。
select
max(`ap`.`name`) AS `name`,
max(`ap`.`description`) AS `description`,
min(`ap`.`price`) AS `price`,
max(`ap`.`image`) AS `image`,
`ap`.`ean` AS `ean`,
max(`ap`.`color`) AS `color`,
max(`ap`.`size`) AS `size`,
max(`ap`.`brand`) AS `brand`,
`ap`.`ean` AS `productId`
from `AllProducts` `ap`
where (not((`ap`.`ean` like '')))
group by `ap`.`ean`
union all
select
`ap`.`name` AS `name`,
max(`ap`.`description`) AS `description`,
min(`ap`.`price`) AS `price`,
max(`ap`.`image`) AS `image`,
'' AS `ean`,
max(`ap`.`color`) AS `color`,
max(`ap`.`size`) AS `size`,
max(`ap`.`brand`) AS `brand`,
md5(lcase(`ap`.`name`)) AS `productId`
from `AllProducts` `ap`
where (`ap`.`ean` = '')
group by `ap`.`name` order by NULL
利用可能な製品が複数ある場合は、利用可能な最長/最短の説明 (または色/サイズなど) が使用されます。必ずしも最長または最短の値が必要なわけではありませんが、任意の値が必要です。
私の質問: このビューのパフォーマンスを向上させるにはどうすればよいですか?
Mani のコメントを使用して、次の状況に切り替えました。これは確かに非常に高速です。
select
`ap`.`name` AS `name`,
`ap`.`description` AS `description`,
a.category,
`ap`.`price` AS `price`,
`ap`.`image` AS `image`,
`ap`.`ean` AS `ean`,
`ap`.`color` AS `color`,
`ap`.`size` AS `size`,
`ap`.`brand` AS `brand`,
case when ap.ean not like '' then ap.ean else md5(lcase(ap.name)) end as productId
from `AllProducts` `ap`
このビューは非常に高速です。ただし、この新しいビューから、名前、説明、カテゴリなどを含む一意の productIds を選択する必要があります (ビューは AllProductsView と呼ばれます)。次のことを試してみたところ、元のクエリよりもクエリが遅くなりました (6.5 秒)。
select max(`apv`.`name`) AS `name`,
max(`apv`.`description`) AS `description`,
max(`apv`.`category`) AS `category`,
min(`apv`.`price`) AS `price`,
max(`apv`.`image`) AS `image`,
max(`apv`.`color`) AS `color`,
max(`apv`.`size`) AS `size`,
max(`apv`.`brand`) AS `brand`,
`apv`.`productId` AS `productId`
from `AllProductsView` `apv`
group by `apv`.`productId`
このクエリを高速化する方法を提案している人はいますか?