精华内容
下载资源
问答
  • 从零开始了解MySQL索引

    千次阅读 2017-04-17 23:29:37
    索引是什么咬文嚼字不一定是坏事,再了解MySQL索引前,我们不妨看看词典中是如何定义索引这个词语的

    索引是什么

    咬文嚼字不一定是坏事,再了解MySQL索引前,我们不妨看看词典中是如何定义索引这个词语的:

    根据一定需要,把书刊中的主要内容或各种题名摘录下来,标明出处、页码,按一定次序分条排列,以供人查阅的资料。

    这里有几个关键点:
    1. 索引的内容是主要内容或题名
    2. 索引的具体手段是标明页码,按顺序排列
    3. 索引的最终目的是供人查阅

    联系到我们实际生活,就是无人不知的新华字典的拼音索引:
    这里写图片描述

    最终目的:帮助我们快速定位到一个字的在字典中的具体位置!

    MySQL中索引

    和字典的索引差不多,帮助我们快速定位记录所在位置,但低层的实现和存储结构不一样。
    通常说的MySQL索引就是B-Tree索引,因为它是用B-Tree这种数据结构来存储数据的。

    那么到底什么是B-Tree呢?

    备注:读B树,而不是B减树,国内早期翻译引起的误会。但是有B+Tree读B加树。

    我们来看看它一颗二叉树如何进化成B-Tree。
    二叉树:根没有父节点,最多有两个子节点;叶子节点没有子节点;其他节点最多有一个父节点,两个子节点。

    二叉查找树:左子树的key值都小于根的key值,右子树的key值都大于根的key值。造成的结果就是存放的数据是有序的,通过中序遍历(左根右)出来就是从小到大的一组数据。
    为什么用查找树:它是特殊的一种二叉树。根据它得存储特性,用二分查找法查找数据比线性查找要快很多。

    二叉平衡树(AVL树):左右子树的高度差不能超过1。超过1就旋转,直到平衡。如何旋转一时半会说不清,暂时抛开不管。总之最终得维持树高度的平衡。
    为什么要旋转:因为二叉树有N种,和key值先后顺序有关。比如下面的两棵树都是二叉查找树,但是右边是最极端的情况,变成了线性结构,但它也满足二叉查找树的定义,但和左边的树比起来查找效率是很低的:
    这里写图片描述

    B-树:为了快速理解,《MySQL技术内幕》给出了最简单的解释:首先它是一种平衡二叉树,所有的记录都是按大小顺序存放在同一层的叶子节点上,各个叶子节点用指针彼此相连(B+树)。最终结果如下图:
    这里写图片描述

    B-Tree索引,就是B-Tree在数据库中的实现。(实际上是B+Tree)。

    创建索引

    根据创建时机:
    1、建表时创建

    CREATE TABLE mytable(
        ID INT NOT NULL,   
        username VARCHAR(16) NOT NULL,  
        INDEX [indexName] (username(length))  
    );

    2、修改表结构时

    ALTER mytable ADD INDEX [indexName] ON (username(length)) 

    3、单独创建索引

    CREATE INDEX indexName ON mytable(username(length)); 

    备注:MySQL中key和index的区别?

    联合索引

    创建联合索引:

    alter table j_position add index idx_county_town_village(county_name,town_name,village_name);

    联合索引是什么?
    本质上就是上面说的B-Tree索引。只不过它得key值是(“凤阳县”,”小溪河镇”,”小岗村”)。
    这些查找情况会使用索引:
    A、查找”凤”开头的县
    B、查找凤阳县并”小”字开头的村,是会使用索引的

    但是,以下情况不会使用索引:
    A、查找”阳”结尾的县
    B、查找”小溪河镇”的镇

    原因——最左前缀匹配。

    展开全文
  • 之前说到日志事件的设计、如何埋点以及基于jvm的程序如何对接我们的系统,接下去我们说下日志如何进行索引。通过前三篇博客可以知道数据通过LOGGER.info等打印日志的函数就可以存入kafka,所以我们对日志建立索引只...
    github开源  欢迎一起维护~~

    之前说到日志事件的设计、如何埋点以及基于jvm的程序如何对接我们的系统,接下去我们说下日志如何进行索引。通过前三篇博客可以知道数据通过LOGGER.info等打印日志的函数就可以存入kafka,所以我们对日志建立索引只需要实时读kafka写入es,为了提高实时索引的速率,我们会部署3个实例实时消费kafka的9个partition,并且使用es的bulk load api,这样测试下来大概3台pc上能够实时每秒索引2w+的数据,实时处理kafka数据写文件大概每秒50w+的处理速度,完全能够满足我们公司现有的日志实时采集索引需求。
    代码比较简单,核心代码如下:
    BulkRequestBuilder bulkRequest = transportClient.prepareBulk();
    int count = 0;
    try {
        while (true) {
            ConsumerRecords<byte[]String> records = this.kafkaConsumerApp.poll(this.kafkaProperties.getPollTimeout());
            if (!records.isEmpty()) {
                for (ConsumerRecord<byte[]String> record : records) {
                    String value = record.value();
                    XContentBuilder source = this.buildXContentBuilder(value);
                    if (source != null) {
                        bulkRequest.add(transportClient.prepareIndex(this.esProperties.getIndex(), this.esProperties.getDoc())
                                .setSource(source));
                    else {
                        LOGGER.info("record transform error, {}"value);
                    }
                    currentOffsets.put(new TopicPartition(record.topic()record.partition()), new OffsetAndMetadata(record.offset() + 1));

                    count++;
                    if (count >= 1000) {
                        // 当达到了1000触发向kafka提交offset
                        kafkaConsumerApp.commitAsync(currentOffsets, new KafkaOffsetCommitCallback());
                        count = 0;
                    }
                }
                int size = bulkRequest.numberOfActions();
                if (size != 0) {
                    bulkRequest.execute().actionGet();
                }
                LOGGER.info("total record: {}, indexed {} records to es"records.count()size);
                bulkRequest = transportClient.prepareBulk();
                kafkaConsumerApp.commitAsync(currentOffsets, new KafkaOffsetCommitCallback());
            }
        }
    catch (WakeupException e) {
        // do not process, this is shutdown
        LOGGER.error("wakeup, start to shutdown, {}"e);
    catch (Exception e) {
        LOGGER.error("process records error, {}"e);
    finally {
        kafkaConsumerApp.commitSync(currentOffsets);
        LOGGER.info("finally commit the offset");
        // 不需要主动调kafkaConsumer.close(), spring bean容器会调用
    }
    该kafka group为es-indexer-consume-group

    /**
     * 根据log字符串构造XContentBuilder
     * @param line
     @return
     */
    private XContentBuilder buildXContentBuilder(String line) {
        try {
            LogDto logDto = new LogDto(line);
            return jsonBuilder()
                    .startObject()
                    .field(Constants.DAYlogDto.getDay())
                    .field(Constants.TIMElogDto.getTime())
                    .field(Constants.NANOTIMElogDto.getNanoTime())
                    .field(Constants.CREATEDlogDto.getCreated())
                    .field(Constants.APPlogDto.getApp())
                    .field(Constants.HOSTlogDto.getHost())
                    .field(Constants.THREADlogDto.getThread())
                    .field(Constants.LEVELlogDto.getLevel())
                    .field(Constants.EVENT_TYPElogDto.getEventType())
                    .field(Constants.PACKlogDto.getPack())
                    .field(Constants.CLAZZlogDto.getClazz())
                    .field(Constants.LINElogDto.getLine())
                    .field(Constants.MESSAGE_SMARTlogDto.getMessageSmart())
                    .field(Constants.MESSAGE_MAXlogDto.getMessageMax())
                    .endObject();
        catch (Exception e) {
            return null;
        }
    }

    由于是进行日志消费,可以允许有一定的丢失和重复消费,但是应该尽量避免。
    代码其实很简单,主要说明下:
    • kafka消费的时候尽量自己控制offset,以防kafka出现异常的时候导致大量的重复消费和丢失当kafka consumer进行rebalance的时候需要将当前的消费者的offset进行提交同步提交offset commitSync(xxx)会等待提交完成异步提交offset commitAsync(xxx, callback)进行异步提交,无需等待
    • 针对以上情况,同步提交我们可以放在rebalance的时候,异步提交应该放在正常消费的时候,并且提交出错需要打印异常进行排查错误
    以上的代码是每1000条进行一个commit,如果以此poll的数据不足1000条也会进行commit,这就既保证了向es提交bulk的效率,同时也能保证正常的offset提交,该方法有一定的重复消费和丢失的情况,因为会出现向es进行了bulk 提交,但是向kafka提交offset的时候程序挂掉,也可能提交了offset之后程序挂掉,但是还没有向es进行bulk提交,但是这种情况比较少见。回头再介绍一篇如果完全确保日志有且仅消费以此的代码,需要用到rollback机制,将offset存入第三方缓存数据。
    加入hook的目的是程序被kill的时候可以确保consumer的线程运行完成再退出。
    展开全文
  • MySQL5.6从零开始学——索引(二)

    千次阅读 2019-03-01 22:40:00
    一、索引简介 1.1索引分类 普通索引,唯一索引,主键索引 单列索引和组合索引(最左前缀) 全文索引(char,varchar,text) 空间索引 Btree索引(InnoDB)和Hash索引 二...

     

    一、索引简介

     

     

    1.1 索引分类

    • 普通索引,唯一索引,主键索引

    • 单列索引和组合索引(最左前缀)

    • 全文索引(char,varchar,text)

    • 空间索引

     

    Btree索引(InnoDB)和Hash索引

     

     

     

     

     

    二、创建索引

     

    2.1 创建表的时候创建索引

     

    2.2 在已经存在的表上创建索引

     

     

     

     

     

     

     

    三、删除索引

     

     

     

     

     

     

     

     

     

     

    展开全文
  • MySQL从零开始 22-索引创建原则

    千次阅读 2018-07-25 18:13:01
     基于合理的数据库设计,经过深思熟虑后为表建立索引,是获得高性能数据库系统的基础。而未经合理分析便添加索引,则会降低系统的总体性能。索引虽然说提高了数据的访问速度,但同时也增加了插入、更新和删除操作的...

     基于合理的数据库设计,经过深思熟虑后为表建立索引,是获得高性能数据库系统的基础。而未经合理分析便添加索引,则会降低系统的总体性能。索引虽然说提高了数据的访问速度,但同时也增加了插入、更新和删除操作的处理时间。

     是否要为表增加索引、索引建立在那些字段上,是创建索引前必须要考虑的问题。解决此问题的一个比较好的方法,就是分析应用程序的业务处理、数据使用,为经常被用作查询条件、或者被要求排序的字段建立索引。基于优化器对SQL语句的优化处理,我们在创建索引时可以遵循下面的一般性原则:

     1. 确定针对该表的操作是大量的查询操作还是大量的增删改操作。 因为索引是以牺牲增删改来提高查询的速度。

     2. 尝试建立索引来帮助特定的查询。检查自己的sql语句,为那些频繁出现在where,group by,order by子句中出现的字段建立索引,即经常用作过滤器的字段上建立索引。 GROUP BY、ORDER BY

     3. 尝试建立复合索引来进一步提高系统性能。修改复合索引将消耗更长时间,同时,复合索引也占磁盘空间。

     4. 对于小型的表,建立索引可能会影响性能。因为索引的查询优势在海量数据的查询时才会体现,如果是小型表,查询优化不明显,而且还降低了增删改的效率,得不偿失。

     5. 在不同值较少的字段上不必要建立索引,如性别字段。

     6. 避免选择大型数据类型的列作为索引。例如长文本数据类型text就不能用于fulltext(全文索引)。

     7. 用于联接union的字段上建立索引;

     8. 在经常存取的多个列上建立复合索引,但要注意复合索引的建立顺序要按照使用的频度来确定。

     9. 在union等集合操作的结果集字段上,建立索引。其建立索引的目的同上。

     10. 考虑使用索引覆盖。对数据很少被更新的表,如果用户经常只查询其中的几个字段,可以考虑在这几个字段上建立索引,从而将表的扫描改变为索引的扫描。

     除了以上原则,在创建索引时,我们还应当注意以下的限制:

    • 限制表上的索引数目

     对一个存在大量更新操作的表,所建索引的数目一般不要超过3个,最多不要超过5个。索引虽说提高了访问速度,但太多索引会影响数据的更新操作。

    • 不要在有大量相同取值的字段上,建立索引

     在这样的字段(例如:性别)上建立索引,字段作为选择条件时将返回大量满足条件的记录,优化器不会使用该索引作为访问路径。

    • 避免在取值朝一个方向增长的字段(例如:日期类型的字段)上,建立索引

     对复合索引,避免将这种类型的字段放置在最前面。由于字段的取值总是朝一个方向增长,新记录总是存放在索引的最后一个叶页中,从而不断地引起该叶页的访问竞争、新叶页的分配、中间分支页的拆分。此外,如果所建索引是聚集索引,表中数据按照索引的排列顺序存放,所有的插入操作都集中在最后一个数据页上进行,从而引起插入“热点”。

    • 对复合索引,按照字段在查询条件中出现的频度建立索引

     在复合索引中,记录首先按照第一个字段排序。对于在第一个字段上取值相同的记录,系统再按照第二个字段的取值排序,以此类推。因此只有复合索引的第一个字段出现在查询条件中,该索引才可能被使用。

     因此将应用频度高的字段,放置在复合索引的前面,会使系统最大可能地使用此索引,发挥索引的作用。

    • 删除不再使用,或者很少被使用的索引

     表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再被需要。数据库管理员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响。

    展开全文
  • MySQL从零开始 19-索引的哲学

    千次阅读 2018-07-25 08:41:12
    因为没有加索引的数据是按顺序的保存在硬盘上的,再查找一个数据时,DBMS会一个一个遍历这些数据来查找,所以时间复杂度为O(n),而且在数据量很多时,它们是硬盘逐次读进内存中的,IO操作的慢速,想必大家都深有...
  • 1 从零开始搭二维激光SLAM — 序章 https://blog.csdn.net/tiancailx/article/details/109777276 2 从零开始搭二维激光SLAM — 前言 https://blog.csdn.net/tiancailx/article/details/109987630 3 从零开始搭二维...
  • 在使用pandas的过程中,我们经常会对数据进行...这样就会将标签重新从零开始顺序排序。不过会发现在数据的表格中会生成一列“index”,表示旧的数据标签。这里可以使用参数设置drop=True解决 df = df.reset_index(drop
  • MySQL的索引类型和实现原理 一、按表列属性分类: 1.普通索引 2.复合索引 二、按数据结构分类: 1.B+tree索引 2.hash索引 3.R tree索引 三、按存储结构分类: 1.聚集索引 2.辅助索引(非聚集索引)   &...
  • 接下去的几篇博客将介绍如何从零开发出一套集侵入的日志采集、日志索引及可视化、基于日志监控报警、基于日志rpc trace跟踪进行系统性能分析的系统,之后都会称为监控中心系统。经测试,该系统的采集以及处理延迟...
  • “System.FormatException”类型的异常在 ...其他信息: 索引(从零开始)必须大于或等于,且小于参数列表的大小。 去掉“,{2}” return string.Format("[{0},{1}]]", strb.ToString(), strData); 修改如下:
  • 写任何有关pandas的代码前,我们应该先导入... 重建索引是Pandas的一个重要方法,主要用于创建一个符合我们需要索引内容的新对象。如果某个索引的值并之前不存在,则会被赋予一个缺失值。 新对象 = Series/Datafr...
  • -- 如果数据表有 PK/Unique 两种约束 , 索引自劢创建 , 除此以外 , 索引必须手劢创建 --  自定义索引语法: -- create index 索引名 on 表名(列名) ; -- 表的主键和唯一约束条件 , 会自动创建索引 create ...
  • -- 如果数据表有 PK/Unique 两种约束 , 索引自劢创建 , 除此以外 , 索引必须手劢创建 --  自定义索引语法: -- create index 索引名 on 表名(列名) ; -- 表的主键和唯一约束条件 , 会自动创建索引 create ...
  • 本文介绍 如何编写表达式语句块 操作“数组与索引器”,比如如何获取或设置数组元素 由或者如何设置索引器元素 然后打印其输出值  OK...那么我们先看看如何一个数组元素中获取其值,本文开始将不会在编写...
  • 这里{0} 0开始
  • 1、全文索引FullText 在定义索引的列上支持值的全文查找,允许在这些索引列中插入重复值和空值,全文索引可以在char、varchar和text中创建,mysql中只有MyISAM支持
  • 错误问题,使用AppendFormat的时候,stringFomart 定义的{0}-{4},后面给的参数少了一个。 StringBuilder dataThisA = new StringBuilder(); string dataThisFomart = "{{ name: \"{0}\", value: {1}, chargvalue:...
  • 原因可能是代码中的占位符不匹配,或者没有按序号依次写好
  • 原因可能是代码中的占位符不匹配,或者没有按序号依次写好,不能缺少或者说跳过某一个占位符数字 如:StringBuilder sb = new StringBuilder(""); int pageCount = (int)...每一行的站位符都应该0 开始算起
  • 在前面提到的,重建索引的问题是必须更新应用中的索引名称。...在运行的集群中可以无缝的一个索引切换到另一个索引 给多个索引分组 (例如, last_three_months) 给索引的一个子集创建 视图 在...
  • 很多小伙伴发现平时在对dataframe进行排序完成后,他的索引是乱的,这样咱们就不好根据元素的下标进行输出了 这种问题怎么解决呢?? 看代码: import pandas as pd data = [['a','3'],['b','1'],['c','2']] df = pd...
  •  在QQ群听那些DBA大牛们讲有关索引知识点的时候发现自己听得一头雾水,很多都听不懂,看来该好好学习下Oracle索引这方面的知识,所以决定在接下来的几天中抽空利用时间来好好钻研下Oracle索引的原理以及相关...
  • 如何解决:System.FormatException:“索引(从零开始)必须大于或等于,且小于参数列表的大小。” 占位符的使用问题。 由于写代码时的粗心,把",“写成了连接符”+",才导致了这个错误。 ...
  • 第一个开始查找,并依次尝试进行匹配,一直到查找到符合要求的值,或者是最后一个项为止。   (3)算法最佳适用情况: ①数据库较小; ②对时间没有苛刻要求。   ( 4 )算法时间复杂度: ...
  • 前言 我们使用Elasticsearch索引文档时,最理想的情况是文档JSON结构是确定的...本篇以实战方式讲解如何停机完成索引重建的三种方案。 外部数据导入方案 整体介绍 系统架构设计中,有关系型数据库用来存储数据,E...
  • ES 索引别名和停机时间

    千次阅读 2016-05-30 15:48:44
    重新索引过程中的问题是必须更新你的应用,来使用另一个索引名。...在一个运行的集群上无缝的一个索引切换到另一个给多个索引分类(例如,last_three_months)给索引的一个子集创建 视图 我们以后会讨论更多别
  • vehicle alias切换到new_vehicle上去,java应用会直接通过index别名使用新的索引中的数据,java应用程序不需要停机,提交,高可用 POST /_aliases { "actions": [ { "remove": { "index": "vehicle", "alias": ...
  • 索引(从零开始)必须大于或等于,且小于参数列表的大小的错位问题” 找了一下原因,最终终于找到了问题出错的原因,就是在values'{1}','{2}'这个地方,定义索引必须从零开始的,所以把这个地方改成values'{0}'...
  • MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等。 7.1 索引简介 索引由数据库表中一列或多列组合而成,其作用是提高对表中数据的查询速度。本节将详细讲解索引的含义、作用、...
  • 一般情况下,索引中的所有类型都会有相似的字段和设置。因此将这些常用设置在_default映射中指定会更加方便,这样就不需要在每次创建新类型的时候都重复设置。_default映射的角色是新类型的模板。所有在_def

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 173,217
精华内容 69,286
关键字:

从零索引