学习MongoDB--(5-2):索引(查看索引的使用,管理索引)

前一篇简单介绍了索引,并给出了基本的索引使用,这一次,我们进一步说一下MongoDB中的索引,包括如何查看查询是否走索引,如何管理索引和地理空间索引等。

【使用explain和hint】

前面讲高级查询选项时,提到过"$explain" 和 ”$hint“可以作为包装查询的选项关键字使用,其实这两个本身就可以作为操作游标的函数调用!游标调用explain函数会返回一个文档,用于描述当 前查询的一些细节信息。这也不同于我们前面介绍的游标函数,前面提到的游标处理函数都是返回游标,可组成方法链调用。我们看一下explain的具体应用

[javascript] view plaincopy

  1. > db.blogs.findOne();
  2. {
  3. "_id" : ObjectId("502262ab09248743250688ea"),
  4. "content" : ".....",
  5. "comment" : [
  6. {
  7. "author" : "joe",
  8. "score" : 3,
  9. "comment" : "just so so!"
  10. },
  11. {
  12. "author" : "jimmy",
  13. "score" : 5,
  14. "comment" : "cool! good!"
  15. }
  16. ]
  17. }
  18. > db.blogs.find({"comment.author":"joe"}).explain();
  19. {
  20. "cursor" : "BtreeCursor comment.author_1",
  21. "nscanned" : 1,
  22. "nscannedObjects" : 1,
  23. "n" : 1,
  24. "millis" : 70,
  25. "nYields" : 0,
  26. "nChunkSkips" : 0,
  27. "isMultiKey" : true,
  28. "indexOnly" : false,
  29. "indexBounds" : {
  30. "comment.author" : [
  31. [
  32. "joe",
  33. "joe"
  34. ]
  35. ]
  36. }
  37. }

我们在集合blogs上为内嵌文档的键“comment.author”建立了索引,然后我们使用这个键作为查询条件查询文档,在游标上调用explain返回上述文档,我们解释一下返回文档几个主要键的含义:

1》 “cursor”:因为这个查询使用了索引,MongoDB中索引存储在B树结构中,所以这是也使用了BtreeCursor类型的游标。如果没有使用索 引,游标的类型是BasicCursor。这个键还会给出你所使用的索引的名称,你通过这个名称可以查看当前数据库下的system.indexes集合 (系统自动创建,由于存储索引信息,这个稍微会提到)来得到索引的详细信息。

2》 “nscanned”/“nscannedObjects”:表明当前这次查询一共扫描了集合中多少个文档,我们的目的是,让这个数值和返回文档的数量越接近越好。

3》 "n":当前查询返回的文档数量。

4》 “millis”:当前查询所需时间,毫秒数。

5》 “indexBounds”:当前查询具体使用的索引

上述我们的文档只是定义了一个内嵌文档的索引,我们查询也正好使用了这个键,这个情况 比较简单。我们再看一个稍微复杂些的情况!集合user上有两个索引{"name":1,“age”:1}和{“age”:1,“name”:1},我们 按照这两个键查询,再看看explain的返回:

[javascript] view plaincopy

  1. > db.user.ensureIndex({"name":1,"age":1});
  2. > db.user.ensureIndex({"age":1,"name":1});
  3. > db.user.find({"age":40, "name":"tim"}).explain();
  4. {
  5. "cursor" : "BtreeCursor name_1_age_1",
  6. "nscanned" : 1,
  7. "nscannedObjects" : 1,
  8. "n" : 1,
  9. "millis" : 0,
  10. "nYields" : 0,
  11. "nChunkSkips" : 0,
  12. "isMultiKey" : false,
  13. "indexOnly" : false,
  14. "indexBounds" : {
  15. "name" : [
  16. [
  17. "tim",
  18. "tim"
  19. ]
  20. ],
  21. "age" : [
  22. [
  23. 40,
  24. 40
  25. ]
  26. ]
  27. }
  28. }
  29. >

我们看,返回文档的键没有区别,其默认使用了索引"name_1_age_1",这是查询优化器为我们使用的索引!我们此处可以通过hint进行更行,即强制这个查询使用我们定义的“age_1_name_1”索引,如下:

[javascript] view plaincopy

  1. > var cursor = db.user.find({"age":40, "name":"tim"}).hint({"age":1,"name":1});
  2. > cursor.explain();
  3. {
  4. "cursor" : "BtreeCursor age_1_name_1",
  5. "nscanned" : 1,
  6. "nscannedObjects" : 1,
  7. "n" : 1,
  8. "millis" : 0,
  9. "nYields" : 0,
  10. "nChunkSkips" : 0,
  11. "isMultiKey" : false,
  12. "indexOnly" : false,
  13. "indexBounds" : {
  14. "age" : [
  15. [
  16. 40,
  17. 40
  18. ]
  19. ],
  20. "name" : [
  21. [
  22. "tim",
  23. "tim"
  24. ]
  25. ]
  26. }
  27. }
  28. >

我们看,hint函数不同于explain函数,会返回游标,我们可以在游标上调用explain查看索引的使用情况!99%的情况,我们没有必要通过hint去强制使用某个索引,MongoDB的查询优化器非常智能,绝对能帮助我们使用最佳的索引去进行查询!

【索引管理】

上面提到索引的元信息(描述信息)存储在集合system.indexes中,这是系 统提供的保留集合(创建数据库时),我们不能对其进行插入或删除操作!我们可以从中查看索引定义的相关信息,我们操作这个集合只能通过 ensureIndex(插入索引),dropIndex(删除索引)两个函数!我们先看看system.indexes这个集合吧:

[javascript] view plaincopy

  1. > db.system.indexes.find();
  2. { "v" : 1, "key" : { "_id" : 1 }, "ns" : "mylearndb.blogs", "name" : "_id_" }
  3. { "v" : 1, "key" : { "_id" : 1 }, "ns" : "mylearndb.people", "name" : "_id_" }
  4. { "v" : 1, "key" : { "_id" : 1 }, "ns" : "mylearndb.users", "name" : "_id_" }

系统会默认为集合创建"_id"唯一性索引,所以这个表会有很多这种“name”为“_id_”的索引信息。键“ns”是“数据库名.集合名”,我们可以通过这个查询一个集合上定义的所有索引:

[javascript] view plaincopy

  1. > db.system.indexes.find({"ns":"mylearndb.user"});
  2. { "v" : 1, "key" : { "_id" : 1 }, "ns" : "mylearndb.user", "name" : "_id_" }
  3. { "v" : 1, "key" : { "name" : 1 }, "unique" : true, "ns" : "mylearndb.user", "name" : "name_1", "dropDups" : true }
  4. { "v" : 1, "key" : { "name" : 1, "age" : 1 }, "ns" : "mylearndb.user", "name" : "name_1_age_1" }
  5. { "v" : 1, "key" : { "age" : 1, "name" : 1 }, "ns" : "mylearndb.user", "name" : "age_1_name_1" }
  6. >

我们也可通过键"name”来查询特定索引的元信息,这里不做演示了。

【修改索引】

随着应用数据的积累或集合结构的改变,老的索引会出现效率低下的问题,修改索引页也是 不可避免了。我们可以随时通过ensureIndex函数为集合添加索引,这个函数前面已经多次使用,这里我们再介绍该函数第二个参数文档的一个 键"background",布尔类型,表明是否在数据库服务空闲时来构建索引,因为索引的构建是一个耗时耗资源的过程,并且在构建过程中,数据库会阻塞 所有的访问请求,对于一个大数量的集合添加索引我们应该启用这个选型!我们还要知道的是,即时启用了这个选项,构建仍会影响正常服务,但不会彻底阻塞数据 库服务:

[javascript] view plaincopy

  1. > db.user.ensureIndex({"name":1,"registered":-1},{"background":true});
  2. >

其使用方式和以前创建索引的过程没有区别。

对于没有用的索引,我们应尽快删除,因为索引会影响数据库的增删改的效率!利用集合的 dropIndex(indexName)删除一个集合上的特定索引。我们使用这个函数的正确步骤应该是先通过查询system.indexes确认索引 的名称,然后再删除,这样做是因为不是所有语言的数据库驱动都是按照我们前面介绍的方式去生成索引名称:

[javascript] view plaincopy

  1. > db.system.indexes.find({"ns":"mylearndb.user"});
  2. { "v" : 1, "key" : { "_id" : 1 }, "ns" : "mylearndb.user", "name" : "_id_" }
  3. { "v" : 1, "key" : { "name" : 1, "age" : 1 }, "ns" : "mylearndb.user", "name" :
  4. { "v" : 1, "key" : { "age" : 1, "name" : 1 }, "ns" : "mylearndb.user", "name" :
  5. > db.user.dropIndex("name_1_age_1");
  6. { "nIndexesWas" : 3, "ok" : 1 }
  7. > db.system.indexes.find({"ns":"mylearndb.user"});
  8. { "v" : 1, "key" : { "_id" : 1 }, "ns" : "mylearndb.user", "name" : "_id_" }
  9. { "v" : 1, "key" : { "age" : 1, "name" : 1 }, "ns" : "mylearndb.user", "name" :
  10. >

我们需要注意,集合还有一个函数dropIndexes,不接受任何参数,这个函数要慎用啊,他会直接将集合所有的索引全部删掉!Shell中还可以通过运行命令的方式删除一个索引:

[javascript] view plaincopy

  1. > db.system.indexes.find({"ns":"mylearndb.user"});
  2. { "v" : 1, "key" : { "_id" : 1 }, "ns" : "mylearndb.user", "name" : "_id_" }
  3. { "v" : 1, "key" : { "age" : 1, "name" : 1 }, "ns" : "mylearndb.user", "name" : "age_1_name_1" }
  4. > db.runCommand({"dropIndexes":"user","index":"age_1_name_1"});
  5. { "nIndexesWas" : 2, "ok" : 1 }
  6. > db.system.indexes.find({"ns":"mylearndb.user"});
  7. { "v" : 1, "key" : { "_id" : 1 }, "ns" : "mylearndb.user", "name" : "_id_" }
  8. >

从上述的例子可看到这个命令的使用情况,其中键"dropIndexes"指明要删除索引所在的集合,键"index"指明要删除的索引的名称!如果这里名称指明为一个“*”,则表明是删除集合上所有的索引!

除此之外,还有一种删除索引的方式是将集合删掉,这样所有索引(包括键“_id”的唯 一索引)、文档都会被删除。上述的删除所有索引的方式都不会删除系统为键“_id”创建的唯一索引。调用集合的remove函数,即使删除所有文档,也不 会删除索引,当你往集合中添加数据时,该索引还会起作用。

MongoDB中,往含有数据的集合上添加索引比向空集合添加索引后插入数据要快一些,这个在进行数据库数据初始化时可以考虑一下。

【地理空间索引】

目前网络上LBS(location based service)越来越流行,有一个应用就是查询你所在位置附件的某些场所。为了提升这种查询的速度(查询不同于上面单维度,需要搜索两个维度),MongoDB为坐标平面查询提供了专门的索引,即称作地理空间索引。

由于建立地理空间索引的键的值必须是一对值:一个包含两个数值的数组或包含两个键的内 嵌文档(内嵌文档的键的名称无所谓),如:{“gps”:[123,134]},{“gps”:{“x”:123,“y”:134}},{“gps”: {“latitude”:123,“longitude”:134}}。这些文档的键“gps”,我们都可以再上面建立地理空间索引:

[javascript] view plaincopy

  1. > db.shopstreet.find();
  2. { "_id" : ObjectId("502673678a84caa12e8070be"), "desc" : "coffeehouse", "gps" : [ 100, 120 ] }
  3. { "_id" : ObjectId("502673738a84caa12e8070bf"), "desc" : "coffeebar", "gps" : [ 110, 130 ] }
  4. { "_id" : ObjectId("502673838a84caa12e8070c0"), "desc" : "coffee king", "gps" : [ 110, 123 ] }
  5. { "_id" : ObjectId("502673a08a84caa12e8070c1"), "desc" : "coffee buck", "gps" : [ 106, 113 ] }
  6. { "_id" : ObjectId("502674028a84caa12e8070c2"), "desc" : "nike shop", "gps" : [ 109, 111 ] }
  7. > db.shopstreet.ensureIndex({"gps" : "2d"});
  8. >

建立地理空间索引同样调用ensureIndex方法,{"gps" : "2d"},以前建立索引键的值为1,或-1,地理空间索引的值固定为"2d"。地理空间索引默认值的范围为(-180~180)(对于经纬度很适合),但我们在创建索引时可以指定其值的范围:

[javascript] view plaincopy

  1. > db.shopstreet.ensureIndex({"gps" : "2d"},{"min":-1000,"max":1000});
  2. >

上面我们创建的地理空间索引值的范围为-1000~1000。

地理空间查询可以通过find或使用数据库命令。这里我们需要使用“$near”查询操作符,如下:

[javascript] view plaincopy

  1. > db.shopstreet.find({"gps":{"$near" : [110,130]}});
  2. { "_id" : ObjectId("502673738a84caa12e8070bf"), "desc" : "coffeebar", "gps" : [ 110, 130 ] }
  3. { "_id" : ObjectId("502673838a84caa12e8070c0"), "desc" : "coffee king", "gps" : [ 110, 123 ] }
  4. { "_id" : ObjectId("502673678a84caa12e8070be"), "desc" : "coffeehouse", "gps" : [ 100, 120 ] }
  5. { "_id" : ObjectId("502673a08a84caa12e8070c1"), "desc" : "coffee buck", "gps" : [ 106, 113 ] }
  6. { "_id" : ObjectId("502674028a84caa12e8070c2"), "desc" : "nike shop", "gps" : [ 109, 111 ] }
  7. >

这个查询会按点(110,130)来查询文档,由远及近将符合条件的文档返回,如果没有在游标上使用limit函数,默认会返回100条文档。通常我们会利用limit限制前几个最靠近的目标文档即可!我们可以使用数据库命令完成上述查询:

[javascript] view plaincopy

  1. > db.shopstreet.ensureIndex({"gps" : "2d"},{"min":-1000,"max":1000});
  2. > db.shopstreet.find({"gps":{"$near" : [110,130]}});
  3. { "_id" : ObjectId("502673738a84caa12e8070bf"), "desc" : "coffeebar", "gps" : [ 110, 130 ] }
  4. { "_id" : ObjectId("502673838a84caa12e8070c0"), "desc" : "coffee king", "gps" : [ 110, 123 ] }
  5. { "_id" : ObjectId("502673678a84caa12e8070be"), "desc" : "coffeehouse", "gps" : [ 100, 120 ] }
  6. { "_id" : ObjectId("502673a08a84caa12e8070c1"), "desc" : "coffee buck", "gps" : [ 106, 113 ] }
  7. { "_id" : ObjectId("502674028a84caa12e8070c2"), "desc" : "nike shop", "gps" : [ 109, 111 ] }
  8. > db.runCommand({"geoNear":"shopstreet", "near":[110,130], "num":3});
  9. {
  10. "ns" : "mylearndb.shopstreet",
  11. "near" : "1111000111111000000111111000000111111000000111111000",
  12. "results" : [
  13. {
  14. "dis" : 0,
  15. "obj" : {
  16. "_id" : ObjectId("502673738a84caa12e8070bf"),
  17. "desc" : "coffeebar",
  18. "gps" : [
  19. 110,
  20. 130
  21. ]
  22. }
  23. },
  24. {
  25. "dis" : 7,
  26. "obj" : {
  27. "_id" : ObjectId("502673838a84caa12e8070c0"),
  28. "desc" : "coffee king",
  29. "gps" : [
  30. 110,
  31. 123
  32. ]
  33. }
  34. },
  35. {
  36. "dis" : 14.142135623730951,
  37. "obj" : {
  38. "_id" : ObjectId("502673678a84caa12e8070be"),
  39. "desc" : "coffeehouse",
  40. "gps" : [
  41. 100,
  42. 120
  43. ]
  44. }
  45. }
  46. ],
  47. "stats" : {
  48. "time" : 0,
  49. "btreelocs" : 0,
  50. "nscanned" : 5,
  51. "objectsLoaded" : 4,
  52. "avgDistance" : 7.04737854124365,
  53. "maxDistance" : 14.142152482638018
  54. },
  55. "ok" : 1
  56. }
  57. >

这个命令接受一个文档,文档中键"geoNear"指明查询的集合,键"near"指 明查询的基准坐标值,键"num"指定返回的结果数量!然后执行后返回如上结果,这个命令同时还会返回每个返回文档距查询点的距离,这个距离的数据单位就 是你数据的单位,如上述数据位经纬度,键“dis”后面的距离数值就是经纬度!

MongoDB不但能找到靠近一个点的文档,还能找到指定形状内的文档!使用查询操作符"$within"即可,同时通过MongoDB提供的查询操作符指定形状,如“$box”可以指定矩形,“$center”可以指定圆形:

[javascript] view plaincopy

  1. > db.shopstreet.find();
  2. { "_id" : ObjectId("502673678a84caa12e8070be"), "desc" : "coffeehouse", "gps" : [ 100, 120 ] }
  3. { "_id" : ObjectId("502673738a84caa12e8070bf"), "desc" : "coffeebar", "gps" : [ 110, 130 ] }
  4. { "_id" : ObjectId("502673838a84caa12e8070c0"), "desc" : "coffee king", "gps" : [ 110, 123 ] }
  5. { "_id" : ObjectId("502673a08a84caa12e8070c1"), "desc" : "coffee buck", "gps" : [ 106, 113 ] }
  6. { "_id" : ObjectId("502674028a84caa12e8070c2"), "desc" : "nike shop", "gps" : [ 109, 111 ] }
  7. > db.shopstreet.find({"gps" : {"$within" : {"$box":[[109,130],[110,120]]}}});
  8. { "_id" : ObjectId("502673838a84caa12e8070c0"), "desc" : "coffee king", "gps" : [ 110, 123 ] }
  9. { "_id" : ObjectId("502673738a84caa12e8070bf"), "desc" : "coffeebar", "gps" : [ 110, 130 ] }

通过{"$box":[[109,130],[110,120]]}指定一个矩形,其左下角和右上角坐标!“$within”指定查询在这个范围内的点。

[javascript] view plaincopy

  1. > db.shopstreet.find();
  2. { "_id" : ObjectId("502673678a84caa12e8070be"), "desc" : "coffeehouse", "gps" : [ 100, 120 ] }
  3. { "_id" : ObjectId("502673738a84caa12e8070bf"), "desc" : "coffeebar", "gps" : [ 110, 130 ] }
  4. { "_id" : ObjectId("502673838a84caa12e8070c0"), "desc" : "coffee king", "gps" : [ 110, 123 ] }
  5. { "_id" : ObjectId("502673a08a84caa12e8070c1"), "desc" : "coffee buck", "gps" : [ 106, 113 ] }
  6. { "_id" : ObjectId("502674028a84caa12e8070c2"), "desc" : "nike shop", "gps" : [ 109, 111 ] }
  7. > db.shopstreet.find({"gps" : {"$within" : {"$center":[[110,130],10]}}});
  8. { "_id" : ObjectId("502673838a84caa12e8070c0"), "desc" : "coffee king", "gps" : [ 110, 123 ] }
  9. { "_id" : ObjectId("502673738a84caa12e8070bf"), "desc" : "coffeebar", "gps" : [ 110, 130 ] }
  10. >

上述是通过指定一个圆形来查询同样的点,{"$center":[[110,130],10]},指定了圆形的圆心坐标和半径!

【复合地理空间索引】

通常我们查找一个位置,不会只是通过坐标去定位,还会添加其他条件,我们构建索引时也可以用上:

[javascript] view plaincopy

  1. > db.shopstreet.find();
  2. { "_id" : ObjectId("502673678a84caa12e8070be"), "desc" : "coffeehouse", "gps" : [ 100, 120 ] }
  3. { "_id" : ObjectId("502673738a84caa12e8070bf"), "desc" : "coffeebar", "gps" : [ 110, 130 ] }
  4. { "_id" : ObjectId("502673838a84caa12e8070c0"), "desc" : "coffee king", "gps" : [ 110, 123 ] }
  5. { "_id" : ObjectId("502673a08a84caa12e8070c1"), "desc" : "coffee buck", "gps" : [ 106, 113 ] }
  6. { "_id" : ObjectId("502674028a84caa12e8070c2"), "desc" : "nike shop", "gps" : [ 109, 111 ] }
  7. > db.showstreet.ensureIndex({"gps":"2d", "desc":1});
  8. >

上述就创建了一个复合地理空间索引,这个索引更符合实际需要!

上述就是MongoDB中索引的使用,索引是数据库查询提升效率的利器,对于任何数据库都是如此!我们应该好好掌握!

http://blog.csdn.net/drifterj/article/details/7853276

学习MongoDB--(5-2):索引(查看索引的使用,管理索引)

时间: 2024-10-09 06:28:00

学习MongoDB--(5-2):索引(查看索引的使用,管理索引)的相关文章

JAVAEE——Solr:安装及配置、后台管理索引库、 使用SolrJ管理索引库、仿京东的电商搜索案例实现

1 学习回顾 1. Lucene  是Apache开源的全文检索的工具包 创建索引 查询索引 2. 遇到问题? 文件名 及文件内容  顺序扫描法  全文检索 3. 什么是全文检索? 这种先创建索引 再对索引进行搜索的过程叫全文检索 4. 索引是什么? 非结构数据中提取一个数据.并重新组合的过程叫索引 5. Lucene实现 6. 入门程序 磁盘文件为原始文件 创建索引 第一步:获取文件 第二步:创建文档对象 第三步:创建分析器 第四步:保存索引及文档到索引库 搜索索引 第一步:用户接口(百度)

学习MongoDB 七: MongoDB索引(索引基本操作)(一)

一.简介 在MongoDB建立索引能提高查询效率,只需要扫描索引只存储的这个集合的一小部分,并只把这小部分加载到内存中,效率大大的提高,如果没有建立索引,在查询时,MongoDB必须执行全表扫描,在数据量大时,效率差别就很明显,对于包括一个没有索引的排序操作的查询,服务器必须在返回任何结果之前将所有的文档加载到内存中来进行排序. 索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构.索引项的排序支持高效的相等匹配和基于范围的查询操作.

Mongodb查看执行计划和强制索引策略

查看执行计划的方法:explain () winningPlan是最终的执行计划 其中的indexBounds索引计划 在age上建立索引 > db.person.ensureIndex({age:1}); {    "createdCollectionAutomatically" : false,    "numIndexesBefore" : 1,    "numIndexesAfter" : 2,    "ok"

Luke 5—— 可视化 Lucene 索引查看工具,可以查看ES的索引

Luke 5 发布,可视化 Lucene 索引查看工具  oschina 发布于2015年08月31日 这是一个主要版本,该版本支持 Lucene 5.2.0. 它支持 elasticsearch 1.6.0(Lucene的4.10.4) 已解决的问题:#20增加支持重建索引并不会存储领域,不暴露位置的字段值. Pull Requests:#23 Elasticsearch 支持和阴影插件组装#26 添加 .gitignore 文件#27 支持 Lucene 5#28 luke.sh 新增LUK

MySQL索引 查看、创建、删除

1.索引类型 创建索引时,可规定索引能否包含重复值.如不包含,则索引应创建为PRIMARY KEY 或 UNIQUE 索引.对于单列惟一性索引,这保证单列不包含重复的值.对于多列惟一性索引,保证多个值的组合不重复. PRIMARY KEY 索引和 UNIQUE 索引非常类似.事实上,PRIMARY KEY 索引仅是一个具有名称 PRIMARY 的 UNIQUE 索引.这表示一个表只能包含一个 PRIMARY KEY,因为一个表中不可能具有两个同名的索引. 2.索引作用 一级索引, 简单的理解可以

Greenplum+Hadoop学习笔记-14-定义数据库对象之创建与管理序列、索引以及视图

6.5.创建与管理序列 序列常用于在新增记录时自动生成唯一标识符,序列的管理包括创建序列.使用序列.修改序列以及删除序列. 6.5.1.创建序列 使用CREATESEQUENCE命令来创建并初始化一个给定名称的单列序列表: devdw=# \h CREATE SEQUENCE                        查看创建序列的帮助 Command:     CREATE SEQUENCE Description: define a new sequence generator Synt

查看索引碎片,并生成重建索引代码

--查看索引碎片: USE dbname SELECT schema_name(T.schema_id) AS Schema_Name,T.Name AS Table_Name,I.name AS Index_Name, I.type AS Index_Type,D.avg_fragmentation_in_percent AS avg_fragmentation_in_percent,page_count into #t_index FROM sys.dm_db_index_physical_

SQL Server 索引维护:系统常见的索引问题

在很多系统中,比如本人目前管理的数据库,索引经常被滥用,甚至使用DTA(数据库引擎优化顾问)来成批创建索引(DTA目前个人认为它的真正用处应该是在发现缺失的统计信息,在以前的项目中,用过一次DTA,里面提示了很多列缺少统计信息,后来在不改动其他操作的前提下,把这些统计信息手动建上去,性能提升非常明显.关于统计信息将另开文章介绍).一个表甚至有20多个索引(索引的数量并没有标准,但是要尽量合理,每个索引都应该能支撑大量查询或者增删改中的查询功能才有存在价值).索引过多带来了服务器的沉重压力,有这么

【索引】Oracle之不可见索引和虚拟索引的比对

[索引]Oracle之不可见索引和虚拟索引的比对    Oracle之不可见索引 :http://blog.itpub.net/26736162/viewspace-2124044/ Oracle之虚拟索引 :  http://blog.itpub.net/26736162/viewspace-2123687/   之前给大家分享过不可见索引和虚拟索引,今天给大家分享的是Oracle之不可见索引和虚拟索引的比对.   比较项目 不可见索引(Invisible Indexes) 虚拟索引(Virt