繁体   English   中英

索引我的表mysql

[英]Indexing my table mysql

我的桌子很大,有超过1亿条记录。 该表的格式如下:

id (AUTO_INCREMENT) - main key | username VARCHAR(100) | email VARCHAR(100) | ip VARCHAR(30) | hash VARCHAR(150) | salt VARCHAR(100)

我是刚接触索引的人,当我运行此查询时,我意识到了潜力:

"SELECT * FROM users WHERE id = 1000000;"

该查询以闪电般的速度提供了数据,而如果我运行其他查询,例如:

"SELECT * FROM users WHERE email = 'test@test.com';"

获取结果将花费一分钟以上的时间,我知道这是因为该表未建立索引。

我要针对该表运行的查询如下:

"SELECT * FROM users WHERE INSTR('email', 'test@');"

"SELECT * FROM users WHERE INSTR('username', 'testuser');"

我可以提供的其他信息是,用户名和电子邮件列不是唯一的。 在创建列时,我没有指定它们是“ DEFAULT NULL”还是“ NOT NULL”。

我想知道索引该表的最佳方法是什么,以便我可以运行上面的查询? 我尝试研究,但我有些困惑。

哦,请注意,我正在使用的数据库是mariadb,后端是innodb。

首先,最好使用SELECT field1, field2, field3 ...来代替查询中实际需要的数据列,而不是使用SELECT *

处理大量数据时,通常的做法是制作许多链接表。 这些表的唯一目的是将一个数据链接到另一个数据。 在您的电子邮件示例中,您可能有一个表来链接ID和电子邮件,然后对这些ID运行查询。

另一个解决方案是使多个表具有相同的架构,并彼此异步运行查询。 如果您有10张桌子而不是1张桌子,则需要6秒而不是1分钟。

首先,索引与列可以具有空值或不具有空值的事实以及列可以具有唯一性或不唯一的事实之间没有关系。

索引在查询中具有很大的优势。 您应该在每个查询参数上创建索引。 例如,根据您发现的查询:

CREATE INDEX index_name
ON table_name (email);

CREATE INDEX index_name2
ON table_name (id, email);

PS:既不需要在主键上也不需要在外键上创建索引。 您应该阅读以获取更多信息。

尝试

CREATE INDEX tableName_indexName
ON tableName (email);

CREATE INDEX tableName_indexName
ON tableName (username);

在我们建立索引之前,有几件事可以改进:):

  • 列定义:
    • id,用户名和电子邮件对我来说似乎很好
    • ip:我将其存储为int unsigned ,然后使用MySQL INET_ATONINET_NTOA函数存储/检索值。 如果您想存储IPv6地址或将IPv4和IPv6混合存储,那么事情会变得有些棘手,但是总体上它是相同的(Google是您的朋友)
    • hash:我从未听说过哈希,哈希的长度可以可变,最多150个字符;)找出哈希的长度,然后使用具有此长度的BINARY字段(如果要存储,则使用长度为两倍的CHAR以十六进制(而不是二进制)表示,例如, SHA-1 BINARY(20)CHAR(40)
    • 盐:最大长度为100的盐似乎对我来说有点高,但无论漂浮在船上的是什么。
  • 查询:您确定要使用INSTR吗? 我问是因为这样一来,您将返回搜索项在文本中任意位置的所有行,例如ThisIsMySuperFancytestuser!!! 特别是对于用户而言,这可能不是您想要的;)此外,这使得无法使用任何索引。 只需做一个简单的SELECT * FROM users WHERE username = 'testuser'; 为用户和SELECT * FROM users WHERE email LIKE 'test@%'; 如果您想使域保持打开状态,请输入电子邮件。 (请注意,[B-Tree索引(您将要使用)]可以与LIKE通配符一起使用,只要它们不在开头,因此SELECT * FROM users WHERE email LIKE '%test@%';能够使用索引[此查询基本上与您的INSTR示例相同],请参见https://dev.mysql.com/doc/refman/5.7/en/index-btree-hash.html

现在,为索引。 您可以简单地添加一个索引,例如CREATE INDEX inx_username ON table (username); 使用索引时有很多微妙之处和技巧,所以我建议您走很长一段路(或Google),至少看看一下MySQL参考: https : //dev.mysql.com/doc/ refman / 5.7 / en / create-index.html-在这里您将学到诸如仅索引一列的前n个字符以节省内存的事情;)

祝好运

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM