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`);

(关于第二个查询的一个奇怪的注释是,如果我在 phpmyadmin 中执行此操作,它需要 100 秒才能完成“如果它完成”,那么它会说它需要 0.024 秒。虽然它加载了 100 秒,但在我的网站上它也需要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

加入会加快您的查询速度吗?

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

我怀疑这是因为比较了涉及非拉丁字符的列。也许这与数据库上定义的排序规则和字符集有关。尝试使用utf8_bin.

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

二进制字符串比较更快,并且在您的情况下可能有意义。我敢肯定,在这种情况下,英语和日语查询的速度应该相同。

JOIN正如约翰指出的那样,也使用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 回答