2010-02-06 85 views
0

所以我有一个独特的CHAR(255)列,我想找到一个特定的行,MySQL搜索长CHAR列,使用较小(substring)CHAR列作为索引?

创建CHAR(10)INDEX使搜索更有效吗? 我知道唯一的也是指数

发动机将扫描throught索引到的第一个字母为J,然后JO,然后JOH 但255个字节×100万条记录的索引,是大量的内存“空间” 扫描,而不只是10字节×百万

mail_sub = LEFT(邮件,10)
mail_sub = SUBSTR(邮件,10)

`CREATE TABLE pwd( 
    id  INT, 
    mail_sub CHAR(10) NOT NULL, 
    mail  CHAR(255) NOT NULL, 
    pw_hash CHAR(32) NOT NULL, 
PRIMARY KEY (id), 
UNIQUE KEY ind_email (mail), 
INDEX  rv_sub (mail_sub,id) 
) ENGINE = INNODB CHARACTER SET latin1;` 

(ID不是AUTO_INCREMENT,其在插入之前定义)

该表读取多达
SELECT * FROM pwd WHERE email='[email protected]';

SELECT * FROM pwd WHERE id=12345;

因此,“ID”或“邮件”可能是主键,我真的不看任何区别;

我的问题是,像

`SELECT * FROM pwd WHERE mail_sub='abcde12345' AND 
email='[email protected]';` 

将让搜索更有效?

优化使用“ind_email”
FORCE /忽略指数坚称没有用,根据文档的MySQL索引提示会被忽略的字符串类型(http://dev.mysql.com/doc/refman/5.1/en/index-hints.html

我想使用JOIN来进行搜索上mail_sub首先,但没有成功

`EXPLAIN EXTENDED 
SELECT a.pw_hash FROM pwd as a 
JOIN pwd as b ON b.id=a.id 
WHERE a.mail_sub='abcde12345' AND b.mail='abc...john.com';` 

你对此有何看法?

谢谢!

回答

0

添加一列散列的电子邮件地址。然后用作谓词where a.hash = hash('[email protected]') and a.email = '[email protected]'

碰巧,mysql包含一个散列函数,称为password(),它产生16个字节的散列。

+0

感谢您的建议----- 是的,我虽然使用MD5()这是16字节(32十六进制),密码()实际上是20字节(40十六进制字符)-----但可以我只在谓词中使用散列? ---你写了'和a.email ='foo @ bar.com'',所以我认为我们不能相信散列是唯一的,虽然MySQL在INSERTion期间确保唯一性,但我最终可能会告诉用户一封电子邮件地址已经注册,什么时候没有,还是我太偏执? – Luxvero 2010-02-07 00:58:53

+0

另外,当我尝试它早些时候使用'where a.hash = hash('[email protected]')和a.email ='foo @ bar.com'' mysql继续使用'email'索引----或者你建议使用哈希列不是唯一的,只是和索引,因此“邮件= xxx”来筛选匹配索引的行?并忘记通过SQL约束强制实施邮件是唯一的? – Luxvero 2010-02-07 01:07:06