首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >提高MySQL效率

问提高MySQL效率
EN

Database Administration用户
提问于 2012-01-24 00:13:05
回答 2查看 164关注 0票数 1
  1. 我有一张桌子,里面有四千三百万张记录。要执行SELECT,我通常选择具有相同字段的记录,比如A。通过不同的A将表分成几个表并保存在数据库中会更有效吗?我能得到多少?
  2. 我有一个名为entry: {entryid (PK), B}的表,包含6000条记录,还有几个具有类似结构的T1: {id(PK), entryid, C, ...}的表,包含超过数百万条记录。以下两个过程是否具有相同的效率?SELECT id FROM T1, entry WHERE T1.entryid = entry.entryid AND entry.B = XXX

和

代码语言:javascript
复制
SELECT entryid FROM entry WHERE B = XXX
//format a string S as (entryid1, entryid2, ... )
//then run
SELECT id FROM T1 WHERE entryid IN S
EN

回答 2

Database Administration用户

回答已采纳

发布于 2012-01-24 15:17:36

在这种情况下,我将首先回答你的第二个问题。

有一种方法可以将查询合并为一体,并有效地执行。

第一个方法是一个查询,其行为如下

  • 通过T1和entry连接entryid,形成一个巨大的临时表
  • 遍历temp表以处理WHERE子句

第二个方法实质上是两个查询。

  • 查找entryid,其中B是某些值
  • 编译字符串中的所有entryid值
  • 使用WHERE entryid IN执行查询
  • 未编入索引的临时表中的协调列表。
  • 将笛卡儿连接回T1以查看哪些值匹配

在这两种情况下,仍然必须形成entryid值的临时表。

您需要做的是重组查询的执行,即a.k.a。重构。

以下是完全重构的第一个查询:

代码语言:javascript
复制
SELECT
    A.entryid
FROM
    (SELECT entryid id FROM entry WHERE B = XXX) A
    LEFT JOIN T1 USING (id)
;

这显示了您的查询,但是它做了两件事。

  1. 它首先使用WHERE子句在entryids列表中组合在一起
  2. 它根据子查询A的长度执行连接

这种重组应该在没有额外的表更改的情况下加速处理。

但是,由于子查询A基于entryid的值获取B值,所以您应该有一个索引来帮助快速收集这些值。请创建此索引:

代码语言:javascript
复制
ALTER TABLE entry ADD INDEX B_entryid_ndx (B,entryid);

使用这个新的重构查询并生成额外的索引,因为重构强制在联接之前发生在何处,因此它将尽可能快。

对于您的第一个问题,重构的查询应该检索它所需的内容,不管是否对其进行分区。分区只是存储引擎选择的练习。

MySQL支持两种分区模式

使用合并存储引擎,不会有很长的迁移路径。映射在2秒内完成。如果没有主键来唯一地标识一个MyISAM表和另一个MyISAM表,那么每个表的维护都可能影响对合并引擎的任何查询。

使用表分区,各个表都内置了一个分区映射。映射可以包括迁移路径。维护只是一个混合袋,因为它将与任何其他桌子。

无论是哪种情况,都需要有一个精心设计的索引方案。为什么?查询的WHERE、ORDER和GROUP子句应该规定真正需要哪些索引来支持查询。

票数 0
EN

Database Administration用户

发布于 2012-01-24 00:30:37

我将考虑使用表分区。您没有提到mysql版本或存储引擎类型。下面是doc链接:

http://dev.mysql.com/doc/refman/5.6/en/partitioning.html

为5.6

票数 1
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/11433

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档