【问题标题】:MySql - WAMP - Huge Table is very slow (20 million rows)MySql - WAMP - Huge Table 非常慢(2000 万行)
【发布时间】:2011-11-14 04:23:35
【问题描述】:

所以我发了this!昨天得到了一个完美的答案,需要先运行这段代码:ALTER TABLE mytable AUTO_INCREMENT=10000001;

我运行了几次,但在 WAMP 几个小时后无法正常工作后重新启动。运行一夜(12小时)后,代码仍然没有运行。

我想知道我的数据库表大小是否超出了 mysql 或我的计算机或两者的限制。

但是,我暗中怀疑正确的索引或其他一些因素可能会极大地影响我的表现。我知道 2000 万行是很多行,但是太多了吗?

我对索引了解不多,只是它们很重要。我尝试将它们添加到名称和状态字段中,我相信我成功了。

顺便说一句,我正在尝试添加一个唯一的 ID 字段,这就是我昨天的帖子的全部内容。

那么,问题是:2000万行是否超出了MySql的范围?如果没有,我是否缺少索引或其他有助于更好地处理这 2000 万行的设置?我可以在所有列上放置索引并使其超快吗?

一如既往,提前谢谢...

以下是规格:

我的电脑是 XP,运行 WAMPSERVER、Win32 NTFS、Intel Duo Core、T9300 @ 2.50GHz、1.17 GHz、1.98 GB 或 RAM

数据库:1 个表,2000 万行 表的大小是: 数据 4.4 Gigs,索引 1.3 Gigs,总计 5.8 Gigs

在“BUSINESS NAME”和“STATE”字段上设置索引

表格字段是这样的:

`BUSINESS NAME` TEXT NOT NULL, 
`ADDRESS` TEXT NOT NULL, 
`CITY` TEXT NOT NULL, 
`STATE` TEXT NOT NULL, 
`ZIP CODE` TEXT NOT NULL, 
`COUNTY` TEXT NOT NULL, 
`WEB ADDRESS` TEXT NOT NULL, 
`PHONE NUMBER` TEXT NOT NULL, 
`FAX NUMBER` TEXT NOT NULL, 
`CONTACT NAME` TEXT NOT NULL, 
`TITLE` TEXT NOT NULL, 
`GENDER` TEXT NOT NULL, 
`EMPLOYEE` TEXT NOT NULL, 
`SALES` TEXT NOT NULL, 
`MAJOR DIVISION DESCRIPTION` TEXT NOT NULL, 
`SIC 2 CODE DESCRIPTION` TEXT NOT NULL, 
`SIC 4 CODE` TEXT NOT NULL, 
`SIC 4 CODE DESCRIPTION` TEXT NOT NULL 

【问题讨论】:

  • 数据库只是喜欢快速磁盘,我看到你的电脑是笔记本电脑(Txxxx CPU),几乎所有笔记本电脑的磁盘都在性能方面很糟糕。不是说 20M 记录是花生,但它也不是一张巨大的桌子。增加允许 MySQL 使用的内存可能也有很大帮助。

标签: mysql phpmyadmin wamp


【解决方案1】:

一些答案​​:

  • 2000 万行完全在 MySQL 的能力范围内。我在一个数据库中工作,该数据库的一个表中有超过 5 亿行。重组一张表可能需要几个小时,但普通查询只要有索引辅助就不是问题。

  • 您的笔记本电脑已经过时,无法用作大型数据库服务器。进行表重组需要很长时间。低内存量和通常较慢的笔记本电脑磁盘可能会限制您。您可能也在使用 MySQL 的默认设置,这些设置是为在非常旧的计算机上工作而设计的。

  • 我不建议对 every 列使用 TEXT 数据类型。大多数这些列没有理由需要TEXT

  • 不要在每一列上都创建索引,特别是如果你坚持使用TEXT 数据类型。除非您定义前缀索引,否则您甚至无法索引TEXT 列。一般来说,选择索引来支持特定的查询。

基于上述内容,您可能还有许多其他问题,但在一篇 StackOverflow 帖子中要涵盖的内容太多了。如果您要使用数据库,则可能需要接受培训或阅读书籍。
我推荐High Performance MySQL, 2nd Edition


您的后续问题:

对于 MySQL 调优,这是一个很好的起点:http://www.mysqlperformanceblog.com/2006/09/29/what-to-tune-in-mysql-server-after-installation/

许多 ALTER TABLE 操作会导致表重组,这意味着基本上锁定表,复制整个表并应用更改,然后重命名新表和旧表并删除旧表。如果表非常大,这可能需要很长时间。

TEXT 数据类型最多可以存储 64KB,这对于电话号码或状态来说是多余的。我会使用 CHAR(10) 作为典型的美国电话号码。我会为美国的一个州使用 CHAR(2)。通常,请使用最紧凑、最节省的数据类型,以支持给定列中所需的数据范围。

【讨论】:

  • 感谢 cmets。实际上,我已经使用 mysql/php 很多年了,只是我从来没有使用过这么大的表。我过去必须处理的大多数表都是一百万行或更少。也就是说,还有很多东西要学。
  • 如果不使用“文本”数据类型,您推荐的电话号码或地址字段的标准数据类型是什么...可以是字母数字,但不是整数.
  • 我已经更改了php.ini/mysql.ini的设置如下: post_max_size = 750M upload_max_filesize = 750M max_execution_time = 5000 max_input_time = 5000 memory_limit = 1000M max_allowed_pa​​cket = 200M(在my.ini中)有没有我应该做的其他明显改变?如果是这样,你能指出我正确的方向吗?最后,我对普通查询没有问题(select * from table where field = x;),这是添加了索引字段,添加了一个似乎压垮了我的电脑的新字段。这是否是您所指的“重组表”可能需要数小时?
【解决方案2】:

这将需要很长时间,因为您只有 2GB 的 RAM 和 6GB 的数据/索引,并且会强制在 RAM 和磁盘之间进行大量的换入/换出。不过,您对此无能为力。

您可以尝试批量运行。

创建一个单独的空表,其中包含 auto_increment 列。然后一次插入一定数量的记录(例如,一次插入 1 个状态)。这可能有助于它更快地运行,因为您应该能够完全在内存中处理这些较小的数据集,而不是分页到磁盘。

如果它也在 dba.stackexchange.com 上,您可能会得到更好的响应。

【讨论】:

    【解决方案3】:

    我相信硬件很好,但您需要更好地节省资源。

    数据库结构优化!

    • 不要使用TEXT
    • 对于电话号码,请使用bigint unsigned。任何符号或字母都必须经过解析和转换。
    • 对于任何其他字母数字列,请使用例如varchar([32-256])
    • 邮编当然是mediumint unsigned
    • 性别应该是enum('Male','Female')
    • 销售额可以是int unsigned
    • 状态应该是enum('Alaska',...)
    • 国家应该是enum('Albania',...)

    构建大型索引时,最快的方法是创建一个新表并执行INSERT INTO ... SELECT FROM ... 而不是ALTER TABLE ...

    将 State 和 Country 字段更改为 enum 将大大减少您的索引大小。

    【讨论】:

    • 您真的不想在int 字段中存储电话号码。
    • 还是错了。对于像 Facebook 这样的大公司,我想现在将其更改为有意义的数据类型更加困难。因为他们也必须更改所有代码,将它们视为 int。
    • 每个电话号码都可以用数字书写,因此没有其他更节省空间的存储方式。
    • 数字,好的。如果我没记错的话,过去世界某些地区除了数字之外还使用了字母。更重要的是,如果我们只假设数字,如果我们使用int,我们将如何区分003571234567803571234567835712345678?我们如何存储001234567(internal 66)
    • 我同意,从全局根级别搜索是唯一的解决方案。我们不同意的是,它是对决定使用int 来存储应该存储为char 的东西所产生的问题的解决方案。当一个人想要做加法、乘法、除法等时,将使用整数。不加或减电话“数字”。它们有时会添加或删除前缀,使用字符串函数可以更好地处理操作。
    猜你喜欢
    • 2015-06-11
    • 2010-12-19
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多