mysql索引怎么重建,或者重新收集索引统计信息

mysql索引怎么重建,或者重新收集索引统计信息,第1张

需要重新创建索引,因为长度不同会认为是两个不同的所索引。

创建和删除索引

索引的创建可以在CREATE TABLE语句中进行,也可以单独用CREATE INDEX或ALTER TABLE来给表增加索引。删除索引可以利用ALTER TABLE或DROP INDEX语句来实现。

(1)使用ALTER TABLE语句创建索引。

语法如下:

alter table table_name add index index_name (column_list)

alter table table_name add unique (column_list)

alter table table_name add primary key (column_list)

其中包括普通索引、UNIQUE索引和PRIMARY KEY索引3种创建索引的格式,table_name是要增加索引的表名,column_list指出对哪些列进行索引,多列时各列之间用逗号分隔。索引名index_name可选,缺省时,MySQL将根据第一个索引列赋一个名称。另外,ALTER TABLE允许在单个语句中更改多个表,因此可以同时创建多个索引。

创建索引的示例如下:

mysql>use tpsc

Database changed

mysql>alter table tpsc add index shili (tpmc )

Query OK, 2 rows affected (0.08 sec)

Records: 2 Duplicates: 0 Warnings: 0

(2)使用CREATE INDEX语句对表增加索引。

能够增加普通索引和UNIQUE索引两种。其格式如下:

create index index_name on table_name (column_list)

create unique index index_name on table_name (column_list)

说明:table_name、index_name和column_list具有与ALTER TABLE语句中相同的含义,索引名不可选。另外,不能用CREATE INDEX语句创建PRIMARY KEY索引。

(3)删除索引。

删除索引可以使用ALTER TABLE或DROP INDEX语句来实现。DROP INDEX可以在ALTER TABLE内部作为一条语句处理,其格式如下:

drop index index_name on table_name

alter table table_name drop index index_name

alter table table_name drop primary key

其中,在前面的两条语句中,都删除了table_name中的索引index_name。而在最后一条语句中,只在删除PRIMARY KEY索引中使用,因为一个表只可能有一个PRIMARY KEY索引,因此不需要指定索引名。如果没有创建PRIMARY KEY索引,但表具有一个或多个UNIQUE索引,则MySQL将删除第一个UNIQUE索引。

如果从表中删除某列,则索引会受影响。对于多列组合的索引,如果删除其中的某列,则该列也会从索引中删除。如果删除组成索引的所有列,则整个索引将被删除。

删除索引的 *** 作,如下面的代码:

mysql>drop index shili on tpsc

Query OK, 2 rows affected (0.08 sec)

Records: 2 Duplicates: 0 Warnings: 0

该语句删除了前面创建的名称为“shili”的索引。

统计信息是数据库基于成本的优化器最重要的参考信息;统计信息不准确,优化器可能给出不够优化的执行计划或者是错误的执行计划。对统计信息的计算分为非持久化统计信息(实时计算)与持久化统计信息。

非持久化统计信息

统计信息没有保存在磁盘上,而是频繁的实时计算统计信息;

每次对表的访问都会重新计算其统计信息;

假设针对一张大表的频繁查询,那么每次都要重新计算统计信息,很耗费资源。

持久化统计信息

把一张表在某一时刻的统计信息值保存在磁盘上;

避免每次查询时重新计算;

如果表更新不是很频繁,或者没有达到 MySQL 必须重新计算统计信息的临界值,可直接从磁盘上获取;

即使 MySQL 服务重启,也可以快速的获取统计信息值;

统计信息的持久化可以针对全局设置也可以针对单表设置。

接下来,详细说 MySQL 统计信息如何计算,何时计算,效果评估等问题。在 MySQL Server 层来控制是否自动计算统计信息的分布,并且来决策是持久化还是非持久化。

一:Merge表的原理及优点在Mysql数据库中,Merge表有点类似于视图。mysql的merge引擎类型允许你把许多结构相同的表合并为一个表。之后,你可以执行查询,从多个表返回的结果就像从一个表返回的结果一样。每一个合并的表必须有完全相同表的定义和结构。

1.1 Mysql Merge表的优点:A. 分离静态的和动态的数据B. 利用结构接近的的数据来优化查询C. 查询时可以访问更少的数据D. 更容易维护大数据集E. 可以通过修改.mrg文件来修改Merge表,当然也可以用alter进行修改,修改后要通过FLUSH TABLES刷新表缓存,此法可以动态增加减少子表

1.2 merge表存储引擎在如下这种使用场合会最为有用:1,2,1 网上这样说:如果需要把日志记录不停的录入MySQL数据库,并且每天、每周或者每个月都创建一个单一的表,而且要制作来自多个表的合计查询,MERGE表这时会非常有效。然而,这项功能有局限性。你只能合并MyISAM表而且必须严格遵守相同的表定义的限制。虽然这看起来好像是一个大问题,但是,如果你使用另外一种表类型(例如InnoDB),这种合并可能就不需要.1.2.2 我的感觉最直接的用途: 可以把很多表的统计使用一张表来统计,方便我们的统计,例如,统一账户有1000个流水表,如果要用sql来做这个,你会想到什么,是union 吗?当然可以,但是你可以试一下,union时表的个数最大是61个,这样是不是不行了;如果你用merge表那就很简单,就可以在一个表里面做你的统计了(merge表应该也有表的限制,但是我没有找到这个说明),统一账户有1000个表,我创建了4个merge表(之前创建了1个,select是报错“Can#39t open file: #39./uni_acct/t_acct_water_504.frm#39(errno: 24)”,然后换成4个,两个其实也可以,哈哈;具体merge表union的表数目限制从测试看应该是503,这个数据不一定准确,只是我的一个测试值(有可能和表的数据量也有关))二 merge表的创建和注意事项:2.1 如何创建merge表基本表:CREATE TABLE TEST_MERGE_1(ID INT(5) NOT NULL,VALUE VARCHAR(100) NOT NULL,PRIMARY KEY(ID))

CREATE TABLE TEST_MERGE_2(ID INT(5) NOT NULL,VALUE VARCHAR(100) NOT NULL,PRIMARY KEY(ID))MERGE表:CREATE TABLE TEST_MERGE(ID INT(5) NOT NULL,VALUE VARCHAR(100) NOT NULL,PRIMARY KEY(ID)) TYPE=MRG_MyISAM INSERT_METHOD=LAST UNION=(TEST_MERGE_1,TEST_MERGE_2)

2.2 说明:

此表结构必须与基本表完全一致,包括列名、顺序(注意主键,索引这些可以不同)。UNION表必须同属一个DATABASE。

2. 此表类似于SQL中的union机制。

3. 基本表类型必须是MyISAM的。

4. 可以通过修改.mrg文件来修改MERGE表,每个基本表的名字占一行。注意:修改后要通过FLUSH TABLES刷新表缓存。

5. 对基本表的更改可以直接反映在此表上。

6. INSERT_METHOD的取值可以是: 0 不允许插入 FIRST 插入到UNION中的第一个表 LAST 插入到UNION中的最后一个表。(4.0之后可用)

7. 定义在它上面的约束没有任何作用,约束是由基本表控制的,例如两个基本表中存在着同样的一个Key值,那么在MERGE表中会有两个一样的Key值。

2.3 注意:

如果是通过修改.mrg文件的方式来修改MERGE表,那么一定要修改后要通过FLUSH TABLES刷新表缓存,否则修改不会生效。最近犯过一次这样的错误。

2.在数据量、查询量较大的情况下,不要试图使用Merge表来达到类似于Oracle的表分区的功能,会很影响性能。我的感觉是和union几乎等价。

3.查询结果及顺序与创建Merge表时联合表的顺序有关。

看下面的例子:

CREATE TABLE `allentest5` (

`a` int(11) NOT NULL default #390#39,

`b` varchar(11) default NULL,

PRIMARY KEY (`a`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1

CREATE TABLE `allentest6` (

`a` int(11) NOT NULL default #390#39,

`b` varchar(11) default NULL,

PRIMARY KEY (`a`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1

CREATE TABLE `allentest_mrg_5`

(

`a` int(11) NOT NULL default #390#39,

`b` varchar(11) default NULL,

primary key(a)

)ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`allentest5`,`allentest6`)/*5在前,6在后*/

CREATE TABLE `allentest_mrg_6`

(

`a` int(11) NOT NULL default #390#39,

`b` varchar(11) default NULL,

primary key(a)

) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`allentest6`,`allentest5`)/*6在前,5在后*/

CREATE TABLE `allentest_mrg_6_noKey` (

`a` int(11) NOT NULL default #390#39,

`b` varchar(11) default NULL

) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`allentest6`,`allentest5`) /*meg 没有 主键*/

原始表里面的数据:

select * from allentest5

+---+---------+

| a | b |

+---+---------+

| 3 | test5_3 |

| 2 | test5_2 |

| 1 | test5_1 |

+---+---------+

select * from allentest6

+---+---------+

| a | b |

+---+---------+

| 1 | test6_1 |

| 2 | test6_2 |

+---+---------+

几个merger表的结果

select * from allentest_mrg_6_noKey where a =1/ *没有主键*/

+---+---------+

| a | b |

+---+---------+

| 1 | test6_1 |

| 1 | test5_1 |

+---+---------+

select * from allentest_mrg_5 where a = 1/*有主键*/

+---+---------+

| a | b |

+---+---------+

| 1 | test5_1 |

+---+---------+

select * from allentest_mrg_6 where a = 1/*有主键*/

+---+---------+

| a | b |

+---+---------+

| 1 | test6_1 |

+---+---------+

select * from allentest_mrg_5

+---+---------+

| a | b |

+---+---------+

| 3 | test5_3 |

| 2 | test5_2 |

| 1 | test5_1 |

| 1 | test6_1 |

| 2 | test6_2 |

+---+---------+

select * from allentest_mrg_6

+---+---------+

| a | b |

+---+---------+

| 1 | test6_1 |

| 2 | test6_2 |

| 3 | test5_3 |

| 2 | test5_2 |

| 1 | test5_1 |

+---+---------+

select * from allentest_mrg_6_noKey

+---+---------+

| a | b |

+---+---------+

| 1 | test6_1 |

| 2 | test6_2 |

| 3 | test5_3 |

| 2 | test5_2 |

| 1 | test5_1 |

+---+---------+</ol>可以看到如下信息:

1) mrg表查询的结果和 union的表顺序一致(见select * from allentest_mrg_5和select * fromallentest_mrg_6);2)mrg主键的问题a.在查询时如果不带条件,这时候查询出来的数据和没有带主键的是一样的(见select * from allentest_mrg_6和 select * from allentest_mrg_6_noKey)b.如果带条件(带有主键的查询),这样之后查询到第一个带有主键的内容(见select * from allentest_mrg_6_noKey where a =1select * from allentest_mrg_5 where a = 1和 select * from allentest_mrg_6 where a = 1) ;因此如果是做统计,那么在创建mrg表时尽量不要增加主键。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/6163161.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-16
下一篇 2023-03-16

发表评论

登录后才能评论

评论列表(0条)

保存