2

product と product_variants という 2 つの大きなテーブルがあります。現在、私は MySQL ビューを使用しています。これは、この SQL ステートメントが何度も必要になるためです。データベース構造は変更できません。

製品:
ID | マスターです | アン | 名前 | 価格 ...

Product_Variants:
ID | PID (Product.ID の FK) | マスターです | アン | 名前 | 価格 ...

ビューmy_viewには、次のような選択が含まれています。

(SELECT * FROM `product`) UNION (SELECT * FROM `product_variants`)

今、次のようなクエリを実行しているとき:

SELECT * FROM my_view WHERE EAN = '11110'

約 0.5 秒から 1 秒かかります。各サブクエリに追加してビューのコンテンツを直接使用すると、where超高速です (~0,004 秒):

(SELECT * FROM `product` WHERE EAN = '11110') UNION (SELECT * FROM `product_variants` WHERE EAN = '11110')

ビューでより高速な方法を使用するにはどうすればよいですか? MySQL 関数に変更する必要がありますか?

ティアマット

4

4 に答える 4

2

基本的な問題は、それらの行をフィルター処理するために where 句が適用される前に、ビュー内のユニオンが (where 句の利点なしで) 実行されることです。

その効果は、両方のテーブルからすべての行を選択して巨大な一時テーブルにし、その一時テーブルに where 句を適用することです。もちろん、インデックスの利点はありません (ベース テーブルに存在する場合でも)。

すべての行を保持するのに対し、重複排除プロセスのために結果から基になるテーブルをマスクする重複を破棄するため、 UNION ALL(単にではなくUNION)を使用してみることができます。UNION ALLUNION


本当の問題はデータベースの設計です。2 つのテーブルは非常に似ているため、行の型を区別するための列を持つテーブルが1 つだけであることは明らかです。isVariantテーブルを変更できない場合は、新しいテーブルを作成できます。

NewProduct
ID | PID (fk to self for variants, null otherwise) | IsMaster | IsVariant | EAN | Name | Price ..

検索対象の列 (この場合は EAN) にインデックスを付けます。

一度簡単に入力できます。古いテーブルとの同期を維持するには、製品情報が変更されるたびに手動で作成スクリプトを切り捨てて再実行するか、古いテーブルでトリガーを使用して自動的に同期を維持することができます。サイトの詳細が何であるかによって異なります。

于 2013-07-22T09:20:46.340 に答える
2

この記事が役に立つかもしれません -http://www.mysqlperformanceblog.com/2007/08/12/mysql-view-as-performance-troublemaker/

基本的な前提は、MySQL ビューは、コードの最適化ではなく、単純な SQL の記述を支援することです。

[The] VIEW は単にマクロまたは一時テーブルとして展開され、その場合、VIEW は一時テーブルに実体化されます (インデックスなし!)

インデックスなし = 遅い選択クエリ。

于 2013-07-22T09:13:55.860 に答える
1

selectステートメントでEXPLAINを使用し、テーブルとインデックスの構造をチェックするため、mysqlコマンドを使用してクエリを分析する必要があります。

コマンドを使用

プロファイリングを設定 = 1;

次に、選択クエリを使用してコマンドを使用します

query1 のプロファイルを表示します。

どの物がどれくらいの時間話しているか結果を確認してください。

そして他のいくつかのインプクエリは

* SHOW CREATE TABLE tbl\G -- エンジン、インデックス

  • SHOW TABLE STATUS LIKE 'tbl'\G -- サイズ

  • EXPLAIN SELECT ...\G -- 非効率の手がかり

  • 「%buffer%」のような変数を表示します。-- 約**

于 2013-07-22T09:24:28.410 に答える
0

両方のテーブルで EAN 列のインデックスを作成してみてください。

これも試してください

explain (SELECT * FROM `product` WHERE EAN = '11110') UNION (SELECT * FROM `product_variants` WHERE EAN = '11110')
于 2013-07-22T09:21:36.227 に答える