- 浏览: 506993 次
- 性别:
- 来自: 大连->北京
文章分类
最新评论
-
春天好:
写的很不错 推荐一个免费好用的云端爬虫开发平台不需要安装环境, ...
web爬虫 -
cpu88:
网络爬虫爬来爬去,网上信息可以瞬间扩散,但是也意味着,没有人愿 ...
web爬虫 -
biaoming:
牛。。学习了。。
MongoDB 关于索引的建议 -
biaoming:
楼主用mongo好早啊。
MongoDB 优化 -
biaoming:
好教程,学习了。。。
MongoDB 优化
用例子来理解索引的概念是再简单不过的方法了。因此我们研究一个索引示例。
假使我们要做一个在线约会的网站。用户的资料就会有很多列,比如country, state/region, city, sex, age, eye color等等。这个站点必须支持这些属性的组合来查询用户资料。也必须支持让用户通过用户最近的在线时间,其他会员的打分等等来排序和限制结果。对于这么个复杂的需求我们怎样来设计索引?
奇怪的是,第一个要决定的就是我们是否必须使用索引排序或者文件排序是否是可接受的。基于索引的排序限定了索引和语句创建的方式。比如,我们不能使用索引的情况是WHERE条件的age在18-25之间,不管语句是否使用了一个索引去排序。
如果MySQL使用了索引的范围查询,它也就不能使用另一个索引来排序了。假如这是个比较常见的查询,我们就得知有很多查询都要用到文件排序。
支持多种类的过滤
现在我们需要知道列具有唯一值的数量以及那些经常出现在WHERE条件后的列。在具有许多唯一值的列创建索引,这样做选择性很高。因为MySQL会高效的过滤掉不需要的值。
country不确定是否具有选择性,但是它可能会在大部分查询语句中出现。SEX列不具有选择性,但是它基本会在每个查询语句中出现。根据以上的想法,我们可以使用前缀为(sex,country)来创建一系列不同组合的索引。
按照传统的思路来说,在选择性低的字段加索引没有什么效果。但是我们为什么把一个选择性低的列放在每个索引的开始部分呢?思路错误了?
我们有两个理由要这么使用。第一个理由就是每个查询都会用到sex。我们甚至可以设计让用户仅能通过一个sex来进行搜索。重要的是,添加这一列也不会有什么弊端,因为我们还有一些技巧在里面。
技巧就是:即使一个查询没有对sex进行一些约束,我们也能通过AND sex IN('m', 'f')保证索引的使用。这么做不会过滤任意的行。因此功能上来说和不包含sex查询的语句一样。然而,我们需要包含这一列,因为这样做会使MySQL使用一个更大前缀的索引。这个技巧比较适用于这个需求,但是如果这个值有太多的不同,这样做就不会工作的很好,因为IN()列表太大了些。
这个例子揭示出一个一般准则:全面的考虑整张表。当你设计索引,不要仅仅思考你现有语句所需的索引类型,还要考虑优化语句。如果你需要一个索引,但是你想到一些语句可能会受到不好的影响,问问自己是否能改变这些语句。你应该把语句和索引一起优化来找到折中的一个方案;你没必要设计一个完美的索引schema.
接下来我们要考虑的是其他WHERE条件的组合并且考虑没有索引的情况下哪些组合会变慢。(sex,country,age)上索引是个显而易见的选择,并且我们也需要在(sex,country,region,age)和(sex,country,region,city,age)上创建索引。
这样会有很多索引的。如果我们想重用索引并且不生成过多的索引组合。我们可以使用IN()的技巧并且废弃(sex,country,age)和(sex,country,region,age)索引。如果它们并没有在搜索表单中,可以指定所有国家的列表或者国家的所有区域来确保符合和索引前缀相等的约束。
这些索引可以满足大部分常用查询的需要,但是我们怎样设计其他一些不常用的搜索条件呢。比如has_pictures, eye_color, hair_color和education?如果这些列选择性低并且不经常使用,我们可以不给它们创建索引并且让MySQL扫描一些额外的行。我们也可以这样做,我们可以把它们添加到age之前并且用到我们之前用到的IN()的方法。
现在你可能会发现,我们创建索引的时候总是把age列放到最后。这个列有啥不同么,为什么要放到最后?我们要尽可能使MySQL是用索引上所有的列,因为只能使用最左端的前缀,直到发现第一个条件为范围查询为止。我们已经提到的其他列在WHERE中都可以用相等的条件,但是age的条件是个范围(比如18-25之间)。
我们也可以转为IN()列表。如age IN(18, 19, 20, 21, 22, 23, 24, 25),但是这种方法并不适合这个类型的查询。我们举例要说明的一般准则就是把范围条件的列放到索引的最后,因此优化器就会尽可能使用索引。
我们已经说过了你可以添加更多的列到索引中并且使用IN()列表覆盖那些并不是WHERE条件一部分的那些列,但是你可能做的过了头就会导致问题的发生。在IN中使用了过多的值,是这些list的组合变得巨大,优化器就要评估这种情况了,并且,这样也会降低查询的速度。考虑下如下的语句:
WHERE eye_color IN('brown','blue','hazel')
AND hair_color IN('black','red','blonde','brown')
AND sex IN('M','F')
优化器会把这些转换为3*4*2组合,并且WHERE条件必须要对每一个进行校验。24个组合并不是很极端的数字。但是如果这个数字变为上千的话就要小心了。旧的MySQL版本在处理大量IN组合的时候会出现很多问题:查询优化器会用很多事前和消耗很多内存。如果组合变得过大,新的MySQL版本会停止评估这些组合 ,但是仍会限制MySQL使用索引。
避免使用多个范围查询
假设我们有个last_online列并且我们的需求是上个星期哪些用户在线:
WHERE eye_color IN('brown','blue','hazel')
AND hair_color IN('black','red','blonde','brown')
AND sex IN('M','F')
AND last_online > DATE_SUB('2008-01-17', INTERVAL 7 DAY)
AND age BETWEEN 18 AND 25
这个查询有个问题:它有两个范围条件。MySQL会使用这两个条件的其中一个,但不能同时使用。如果last_online约束单独出现,或者如果last_online的选择性多余age,我们可能希望添加另一系列的索引,要把last_online放在最后。但是,如果我们不能把age转为IN()列表,并且必须要在这两个条件同时出现来提高查询速度,怎么办?这种情况下,没有什么直接的方法,但是我们可以把一个范围条件转化为一个等值比较。为了这样做,我们添加了个active列,我们要周期性的维护它。当用户登录的时候我们会把这个列设为1,并且如果用户连续7天没有登录,会把它设为0。
这个方法可以让MySQL使用如(active, sex, country, age).这样的索引。这个列可能不是很精确,但是这种类型的查询要求的精确度低。如果我们需要精确地结果,我们可以在WHERE条件中加入last_online,当时不要索引它。这个方法有些像我们上几节说过的模拟HASH索引。这个条件不会使用任何的索引,但是因为它不太可能抛弃那些加上索引并没有太多好处的行。也就是说,没有索引也不太影响查询。
目前为止,你可能看到了一个模式:如果既想看活动的,也要看不活动的用户,我们可以添加IN()列表。我们已经添加了太多的列表了,但是可选择的是可以创建独立的索引来满足不同条件的组合。我们已经用了如下索引:(active,sex,country,age), (active,country,age), (sex,country,age), (country,age).虽然这些索引对于特有的查询都是最优的,但是就有维护的消耗,占有的空间,也可能使这种索引策略变得很失败。
这是个优化方式影响优化索引的例子。如果未来的MySQL版本可以放宽索引的扫描,它应该做到在单独索引上使用多个范围查询,因此我们也不必使用IN()列表了。
对于排序的优化
这个示例中我们所关心最后一个优化就是排序。排序小量规模的数据使用文件排序是很快的,但是如果有百万级别的呢?比如,查询条件只有个SEX的情况?
对于这种低选择性的情况,我们可以添加特殊的索引。比如,一个索引(sex,rating)可以适用于下列查询:
SELECT <cols> FROM profiles WHERE sex='M' ORDER BY rating LIMIT 10;
这个查询有ORDER BY 和LIMIT,并且它如果没有索引会非常之慢。
即使加上了索引,如果用户接口是分页并且用户请求的页并不是靠近数据开始的位置,查询还是很慢。语句如下:
mysql> SELECT <cols> FROM profiles WHERE sex='M' ORDER BY rating LIMIT 100000, 10;
这样的语句还是有问题,和加不加索引没什么关系。因为太高的数据偏移导致了MySQL不得不扫描没用的行。反规范的,提前计算的,缓存可能是处理这种语句比较好的方法。一个更好点的策略是限制用户可以查看的页数。这不太会影响用户体验,因为不会有人关心10000页以后的查询结果。
另一个优化这种语句比较好的方法是使用一个覆盖索引去重新获取行的主键。你能连接这个返回的表获得所需要的列。这些可以最小化MySQL的工作量,这些工作就是MySQL必须要收集它所要抛弃的数据。下面的例子就是针对这个语句的优化
mysql> SELECT <cols> FROM profiles INNER JOIN (
-> SELECT <primary key cols> FROM profiles
-> WHERE x.sex='M' ORDER BY rating LIMIT 100000, 10
-> ) AS x USING(<primary key cols>);
发表评论
-
查询性能的优化 - 语句执行的基础 - 查询优化的过程 (一)
2010-01-20 12:00 3504在语句生命周期的下一步就是把一个SQL查询放入一个可执行 ... -
查询性能的优化 - 语句执行的基础 - 已缓存的查询语句
2009-12-01 09:58 1216在解析一个查询之前,如果缓存开启,MySQL要检查它的缓存。这 ... -
查询性能的优化 - 语句执行的基础 - MySQL 客户端/服务端 协议
2009-12-01 01:25 1958MySQL 客户端/服务端 协 ... -
查询性能的优化 - 语句执行的基础
2009-11-30 00:36 1050如果你想从MySQL服务器获得很高的性能,建议你花费一定的时间 ... -
查询性能的优化 - 重新构建查询的方法 - 分解JOIN查询
2009-11-29 11:54 1865分解JOIN查询 许多高性能的网站都分解了JOIN查询。你可 ... -
查询性能的优化 - 重新构建查询的方法 - 拆分一个查询语句
2009-11-28 23:17 1530拆分一个查询语句 另一个分解查询的方法是分步解决。本质上来 ... -
查询性能的优化 - 重新构建查询的方法 - 复杂查询VS多个查询语句
2009-11-28 01:32 1551当开始优化有问题的查 ... -
查询性能的优化 - 查询慢的基础知识:优化数据访问
2009-08-19 14:50 1665一个查询执行的不是 ... -
查询性能的优化 - 前言
2009-08-12 16:49 1022上一章,我们解释了怎样优化schema.这是高性能的一个必要条 ... -
Schema的优化和索引 - 关于存储引擎的简单记录
2009-08-12 15:26 1099这一章的结束,我们来说一下关于设计模型的存储引擎的选择,这些你 ... -
Schema的优化和索引 - 加速ALTER TABLE
2009-08-12 14:02 1878当对于一个大表进行ALTER TABLE的时候,性能问题就产生 ... -
Schema的优化和索引 - 范式和非范式
2009-08-12 11:35 1718有很多方法来展现给定的数据。从完全范式到完全的非范式以及介于两 ... -
Schema的优化和索引 - 索引和表的维护
2009-08-10 15:38 1456当你已经创建了一张表 ... -
Schema的优化和索引 - 高性能的索引策略 - 索引和锁
2009-07-31 15:48 1049InnoDB中,索引所扮演的角色是非常重要的。因为它们可以能让 ... -
Schema的优化和索引 - 高性能的索引策略 - 冗余和重复的索引
2009-07-31 11:37 2093MySQL可以在一个列上创建多个索引;这么做并不会提醒和防止发 ... -
Schema的优化和索引 - 高性能的索引策略 - 压缩索引(Packed Indexes)
2009-07-30 21:30 1453MyISAM使用前缀压缩来降低索引的大小,这样就可以把更多的索 ... -
Schema的优化和索引 - 高性能的索引策略 - 使用索引扫描来进行排序
2009-07-28 10:43 2230MySQL有两种方法生成有序的结果:使用文件排序或者按顺序的扫 ... -
Schema的优化和索引 - 高性能的索引策略 - 覆盖索引(Covering Indexes)
2009-07-22 15:25 2613索引是高效找到行的一 ... -
Schema的优化和索引 - 高性能的索引策略 - 聚簇索引(Clustered Indexes)
2009-07-20 23:29 3171聚簇索引并不是一个独立的索引类型。确切的说它们是存储数据的一个 ... -
Schema的优化和索引 - 高性能的索引策略 - 前缀索引和索引的选择性
2009-07-13 22:32 1806有的时候你可能需要索 ...
相关推荐
首先,我们通过一个具体的例子来了解MySQL中的索引及其优化方法。在给定的内容中,展示了一个名为`employees`的表的创建语句: ```sql CREATE TABLE `employees` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name`...
`scrape_schema_recipe-0.1.3-py2.py3-none-any.whl` 是一个针对Python开发者的库,主要用于后端数据抓取和结构化数据处理。这个库的名称暗示了它的主要功能可能与网络爬虫(scraping)和Schema.org标准有关,可能...
MySQL Schema Sync是一个用于同步MySQL数据库表结构的工具,它能够帮助开发者在多个数据库实例之间保持数据表结构的一致性。这个工具特别适用于那些需要在开发、测试和生产环境之间进行数据库迁移或者版本控制的场景...
DB2提供了多种工具来帮助用户管理和优化索引,其中“db2advis”索引分析器是一个非常有用的工具,它能够为用户提供有关如何改进查询性能的建议。 #### 一、DB2索引分析器简介 “db2advis”是一个用于分析和优化...
首先,我们来看创建的`employees`表结构,包含`id`(主键)、`name`、`age`、`position`和`hire_time`等字段,并创建了一个名为`idx_name_age_position`的联合索引,包含了`name`、`age`和`position`三个字段。...
本示例提供了一个简单的Schema讲解,通过源码分析,我们可以深入理解Schema的实际应用和重要性。 首先,让我们来了解一下Schema的基本概念。在数据库领域,Schema是数据库的逻辑结构,包括表格、列、索引等元素的...
在Oracle数据库中,"方案"(Schema)是一个非常关键的概念,它相当于数据库中的一个用户空间,包含了该用户的所有对象,如表、视图、索引、存储过程等。在本压缩包"sample_schema_scripts"中,包含了一系列用于创建...
### Solrconfig.xml 和 Schema.xml 说明 #### Solrconfig.xml 概述 Solrconfig.xml 是 Apache Solr 的核心配置文件之一,主要用于定义 Solr 实例如何处理文档的索引与查询请求。该文件中包含了多种配置项,用于...
"HR"示例方案是Oracle数据库中的一个标准样例,它包含了一系列与人力资源管理相关的表,如员工、部门、职位等。这个方案通常用于教学和演示目的,展示了Oracle数据库在处理企业级数据时的复杂性和灵活性。 `hr_main...
WebSolrDemo是一个示例项目,它展示了如何在Web应用中实现全文检索和全文索引功能,使用的核心技术是Apache Solr。Apache Solr是一款开源的企业级搜索平台,能够处理大量数据并提供高效的全文检索能力。 全文检索是...
本项目示例是针对Solr 5.5.4版本的一个实践应用,旨在帮助用户了解并掌握Solr的基本操作,包括对索引的增加、删除、修改和查询。 1. **Solr安装与配置**:首先,你需要下载Solr 5.5.4版本,并解压到本地文件系统。...
在Oracle数据库中,Schema是一个非常重要的概念,它代表了数据库对象的集合,这些对象包括但不限于表格、视图、序列、存储过程、同义词、索引、簇和数据库链接等。Schema是逻辑结构,直接与数据库的数据相关,帮助...
在“laravel-spec-schema-master”这个压缩包中,可能包含了实现上述功能的源代码、示例、文档以及安装和使用的说明。通过研究和使用这个扩展,开发者可以更好地定制他们的Laravel项目,以适应特定数据库系统的特性...
"db-sample-schemas-19c.zip" 是一个包含了该数据库版本的示例模式的压缩包,这些模式对于学习、测试和演示Oracle数据库的功能非常有用。在本文中,我们将深入探讨这些示例模式以及它们在Oracle 19c中的应用。 首先...
在使用MySQL的过程中,我们经常会遇到一个名为`information_schema`的数据库。这个数据库在MySQL安装时自动生成,并且对于理解和管理MySQL系统具有重要作用。本文将详细介绍`information_schema`的功能、结构以及...
标题中的“schema-compare-开源”表明我们讨论的是一个用于比较数据库模式的开源工具,而“schema-compare”就是这个工具的名字。这个工具是用 PHP 编写的,它旨在帮助开发者对比并分析两个不同的数据库模式,以找出...
"schema-generator-ui" 是一个可能的项目或工具的名称,主要关注于数据模式(schema)的生成和用户界面。在IT行业中,数据模式通常用于定义数据结构和规则,特别是在数据库设计、API接口定义以及JSON Schema等领域。...
总结,"mysql数据示例"主要涵盖了MySQL数据库的基础知识,包括数据库和表的概念、SQL语言的应用、索引的重要性、事务处理、备份恢复策略以及安全性管理和性能优化等内容。通过学习这些知识,您可以更好地理解和操作...
### 重建索引示例与知识点解析 #### 标题:重建索引例子 DBCC dbreindex dbcc showcontig #### 描述:本示例通过使用`dbcc showcontig`来展示索引碎片化情况,并利用`dbcc dbreindex`命令对指定表的索引进行重组。...
根据给定文件的信息,我们可以总结出以下Oracle数据库相关的知识点: ...综上所述,通过对索引的创建、管理和监控等操作的学习,可以帮助我们更高效地使用Oracle数据库,提高系统的性能和稳定性。