0

私のMySQLデータベースの簡略化されたバージョンは次のようになります:

Table books (ENGINE=MyISAM)
id <- KEY
publisher <- LONGTEXT
publisher_id <- INT <- This is a new field that is currently null for all records

Table publishers (ENGINE=MyISAM)
id <- KEY
name <- LONGTEXT

現在、books.publisher は繰り返される値を保持していますが、publishers.name は一意に保持されています。books.publisher を取り除き、代わりに books.publisher_id フィールドに値を入力したいと考えています。

私がやりたいことを説明する簡単な SQL コードは次のとおりです。

UPDATE books 
JOIN publishers ON books.publisher = publishers.name 
SET books.publisher_id = publishers.id;

問題は、私が大量のレコードを持っているということです。

事前にこのようなものを使用するよりも速い解決策はありますか?:

CREATE INDEX publisher ON books (publisher(20));
4

3 に答える 3

2

あなたの質問のタイトルは、「..最適化...インデックスを使用せずにクエリを実行しますか?」と言っています。

インデックスの使用に対して何を持っていますか?

クエリの実行速度が遅い場合は、常に実行計画を調べる必要があります。publishers一致を見つけるために、各行のテーブルをスキャンする必要があると思います。publishers.nameのルックアップを高速化するためにインデックスをオンにすることは理にかなっていますid

後でインデックスを削除できますが、他の変更が行われるまでプロセスをしばらく実行する必要があるため、そのままにしても害はありません。publishersテーブルは頻繁に更新されないので、テーブルのパフォーマンスはINSERT問題にならないと思いUPDATEます。

于 2013-11-01T13:12:10.907 に答える
1

ここには、最適化によって解決できる可能性のある問題がいくつかあります。

まず、数千行は「大」ではなく「中」です。

第二に、MySQL で「インデックスなしでこれを行いたい」と言うのは、「ニューヨーク市まで車を運転したいのですが、タイヤがパンクしていて、タイヤに空気を入れたくない」と言っているようなものです。リムで運転しているならニューヨーク?」

3 番目に、LONGTEXT発行元のアイテムを使用しています。のような完全にインデックス可能なデータ型を使用しない理由はありVARCHAR(200)ますか? これを行うと、WHERE ステートメントの実行速度が速くなります。大規模な図書館の目録システムでは、出版社フィールドの長さが制限されているため、システムでも制限できます。

第 4 に、あなたのコメントの 1 つから、これは 1 回限りの変換ではなく、定期的なデータ メンテナンスの更新のように見えます。したがって、取引全体を何度も繰り返さないようにする方法を理解する必要があります。私はここで推測していますが、booksテーブルに新しく挿入された行の publisher_id はゼロのように見え、クエリはその列を有効な値に更新します。

それで、ここで何をすべきかです。まず、tables.publisher_id にインデックスを付けます。

次に、メンテナンス クエリの次のバリアントを実行します。

UPDATE books 
  JOIN publishers ON books.publisher = publishers.name 
   SET books.publisher_id = publishers.id
 WHERE books.publisher_id = 0
 LIMIT 100;

これにより、更新がまだ更新されていない行に限定されます。また、一度に 100 行を更新します。毎週のデータ メンテナンス ジョブで、MySQL がクエリが 0 行に影響したことを通知するまで、このクエリを再発行します (php-to-mysql インターフェイスで mysqli::rows_affected または同等のものを見てください)。これは、データベースの更新の進行状況を監視し、更新操作が手に負えなくなるのを防ぐ優れた方法です。

于 2013-11-01T13:23:35.220 に答える
-1

更新クエリの構文が無効ですが、後で修正できます。より高速に実行する方法は、必要なレコードのみを更新するように where 句を追加することです。

于 2013-11-01T13:00:27.967 に答える