1

問題のテーブルが 3 つあります。

`eng` with column english
`jap` with column japanese
`eng-jap` with column eng and column jap

eng.english は独自の英文、jap.japanese は独自の日本語文、eng-jap は jap からの日本語と eng からの英語を含む翻訳です。

この質問の最後に、テーブルの詳細を貼り付けました。

私の質問: なぜ...

このクエリは非常に高速に動作します。

SELECT * FROM eng WHERE english IN (SELECT eng FROM `eng-jap`);

これには100秒またはタイムアウトがかかります:

SELECT * FROM jap WHERE japanese IN (SELECT jap FROM `eng-jap`);

(この 2 番目のクエリに関する奇妙な注意点は、phpmyadmin で実行すると、「終了した場合」が終了するまでに 100 秒かかり、「終了した場合」は 0.024 秒かかったと言うということです。100 秒間ロードされましたが、私の Web サイトでも100 秒またはタイムアウト)

以下のデータからわかるように、これら 3 つのテーブルはすべて、ほぼ同じ数の行を持っています。eng テーブルと jap テーブルは特に似ています。

問題はテーブル設定またはインデックスなどのどこかにあると思われるので、関連するすべての詳細を今すぐ貼り付けます。

JAP TABLE:

Keyname Type    Unique  Packed  Column  Cardinality Collation   
PRIMARY BTREE   Yes     No      ID          130296      A       
full    BTREE   Yes     No      japanese    130296      A       

Format  dynamic
Collation   utf8_general_ci
Rows    130,296
Row length ø    264
Row size ø  372 B
Next Autoindex  131,790

Type    Usage
Data    33,718.6    KiB
Index   13,652.0    KiB
Total   47,370.6    KiB

ENG TABLE:

Keyname Type    Unique  Packed  Column  Cardinality Collation
PRIMARY BTREE   Yes     No      ID      129637      A
full    BTREE   Yes     No      english 129637      A

Format  dynamic
Collation   utf8_general_ci
Rows    129,637
Row length ø    101
Row size ø  181 B
Next Autoindex  130,749

Data    12,899.3    KiB
Index   10,068.0    KiB
Total   22,967.3    KiB

ENG_JAP TABLE:
Keyname Type    Unique  Packed  Column  Cardinality Collation
PRIMARY BTREE   Yes     No      ID          139442  A
eng     BTREE   Yes     No      eng (150)       0   A
                            jap (150)           139442  A

                                Format  dynamic
Collation   utf8_general_ci
Rows    139,442
Row length ø    315
Row size ø  468 B
Next Autoindex  140,951

Data    42,945.5    KiB
Index   20,816.0    KiB
Total   63,761.5    KiB
4

2 に答える 2

0

これは、非ラテン文字を含む列の比較が原因であると思われます。おそらく、それはデータベースで定義された照合と文字セットに関係しています。で試してくださいutf8_bin

ALTER DATABASE `myDb` CHARACTER SET utf8 COLLATE 'utf8_bin';

バイナリ文字列の比較はより高速であり、あなたの場合には理にかなっているかもしれません。この場合、英語と日本語のクエリは同じ速度で表示されるはずです。

JOINJohnが指摘するようにsも使用します

編集: OPのコメントに答えるには、

SELECT * FROM eng WHERE english NOT IN (SELECT eng FROM `eng-jap`);

より効率的に次のように書くことができます:

SELECT * 
FROM   eng c 
WHERE  NOT EXISTS (SELECT * FROM `eng-jap` t WHERE c.english = t.eng);

また

SELECT     c.* 
FROM       eng c 
LEFT JOIN `eng-jap` t ON c.english = t.eng 
WHERE      t.eng IS NULL;

どちらがより速く機能するかはわかりませんJOINが、私のテストNOT EXISTSではより高速でした。データに依存しているのはそれだけかもしれません。自分で試してみてください。

于 2012-11-13T06:18:28.003 に答える
0

参加するとクエリが高速化されますか?

SELECT * 
FROM   jap a INNER JOIN `eng-jap` b ON
            a.japanses = b.jap
于 2012-11-13T05:21:20.093 に答える