【问题标题】:Massive DB and mysql海量数据库和mysql
【发布时间】:2011-06-12 09:45:10
【问题描述】:

我们正在进行的一个新项目需要大量数据分析,但我们发现这非常缓慢,我们正在寻找通过软件和/或硬件改变我们方法的方法。

我们目前在亚马逊 ec2 实例 (linux) 上运行:

High-CPU Extra Large Instance

7 GB of memory
20 EC2 Compute Units (8 virtual cores with 2.5 EC2 Compute Units each)
1690 GB of instance storage
64-bit platform
I/O Performance: High
API name: c1.xlarge


processor       : 7
vendor_id       : GenuineIntel
cpu family      : 6
model           : 26
model name      : Intel(R) Xeon(R) CPU           E5506  @ 2.13GHz
stepping        : 5
cpu MHz         : 2133.408
cache size      : 4096 KB

MemTotal:      7347752 kB
MemFree:        728860 kB
Buffers:         40196 kB
Cached:        2833572 kB
SwapCached:          0 kB
Active:        5693656 kB
Inactive:       456904 kB
SwapTotal:           0 kB
SwapFree:            0 kB

数据库的一部分是文章和实体以及链接表,例如:

mysql> DESCRIBE articles_entities;
+------------+--------------+------+-----+---------+-------+
| Field      | Type         | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| id         | char(36)     | NO   | PRI | NULL    |       | 
| article_id | char(36)     | NO   | MUL | NULL    |       | 
| entity_id  | char(36)     | NO   | MUL | NULL    |       | 
| created    | datetime     | YES  |     | NULL    |       | 
| modified   | datetime     | YES  |     | NULL    |       | 
| relevance  | decimal(5,4) | YES  | MUL | NULL    |       | 
| analysers  | text         | YES  |     | NULL    |       | 
| anchor     | varchar(255) | NO   |     | NULL    |       | 
+------------+--------------+------+-----+---------+-------+
8 rows in set (0.00 sec)

从下表可以看出,我们有很多协会以每天 100,000+ 的速度增长

mysql> SELECT count(*) FROM articles_entities;
+----------+
| count(*) |
+----------+
|  2829138 | 
+----------+
1 row in set (0.00 sec)

像下面这样的简单查询花费了太多时间(12 秒)

mysql> SELECT count(*) FROM articles_entities WHERE relevance <= .4 AND relevance > 0;
+----------+
| count(*) |
+----------+
|   357190 | 
+----------+
1 row in set (11.95 sec)

我们应该考虑什么来缩短查找时间?不同的数据库存储?不同的硬件。

【问题讨论】:

  • 您的表格是否正确编入索引?
  • 从提供的表转储中不是很明显吗?
  • 您是否考虑过使用除 char 之外的其他内容作为 id?在 PostgreSQL 设置中,我在具有 +2000 万条记录和 +5 亿条记录的表之间进行内部连接,使用数字 ID 产生了显着差异。速度要快得多。
  • 能否请您为您提供的慢速 SELECT 发表解释?
  • 也许您的第一步应该是聘请具有优化大型系统经验的数据库专业人员。从您的设计(A char(36) PK?)和您没有这样的人的问题中可以清楚地看出。高性能的大型数据库设计和调优不应该由业余爱好者完成。这不是可以从诸如此类的板上的问题中解决的问题。

标签: mysql database-design optimization nosql


【解决方案1】:

按照 mrorigo 的要求,请提供 SHOW CREATE TABLE articles_entities,以便我们查看您的表的实际索引。

作为 MySQL 文档http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html的注释

如果表有一个多列索引,优化器可以使用索引的任何最左边的前缀来查找行。
例如,如果您在 (col1, col2, col3) 上有一个三列索引,则您在 (col1)、(col1, col2) 和 (col1, col2, col3) 上有索引搜索功能。

如果列不构成索引的最左前缀,则 MySQL 无法使用索引

因此,如果 relevance 是多列索引的一部分,但不是该索引的最左侧列,则该索引不会用于您的查询。

这是一个经常被忽视的常见问题。

【讨论】:

    【解决方案2】:

    使用 char(36) 作为键并不是 MySQL 所能做到的最快速度。如果可能,请使用 INT 类型的键。如果您索引 CHAR 列,与 (BIG)INT 索引相比,索引将非常大(如果没有“正确”创建)

    但是,如果您的列值不是数字,则您会遇到 CHAR 列(仍然比 VARCHAR 快,但可以创建大型索引)。

    请提供表的SHOW CREATE TABLE 以查看键/索引参数,并且正如前面的答案所说,对有问题的查询的解释可以帮助提供更好的答案。

    PS。使用SHOW TABLE STATUS LIKE '{table_name}' 查看表的索引(和数据)大小。

    【讨论】:

      【解决方案3】:

      就查询性能而言,有三件事很重要:

      索引。 记忆。 其他一切。

      首先要做的是检查您的索引。对您的查询进行解释,以了解 MySQL 是如何处理它们的。

      如果这看起来很合理,那么接下来就是检查内存。您的总数据库有多大?现在内存很便宜,从内存运行的查询将比必须从磁盘读取的查询快得多。

      在您探索了这些之后,如果性能仍然很慢,那么可能是时候考虑其他选项了。

      【讨论】:

      • 是的,以上都完成了,所以问题来了,你能提供任何指点吗?
      • 在讨论索引之前,我们需要了解磁盘 i/o。对于耗时 12 秒的查询,需要多少磁盘 i/os? DBMS 使用的查询策略是什么?是全表扫描吗?从那里我们可以转到索引策略。
      猜你喜欢
      • 2013-09-13
      • 2013-06-17
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多