精华内容
下载资源
问答
  • Lucene多线程创建索引及多目录下查询索引
    千次阅读
    2016-04-29 15:02:07

    目的:公司最近要求建立对数据库内多表的索引文件,来实现对数据库数据处理的全文检索
    表有多个,内容风别是不同表内的字段。选用了IK分词和Lucene实现。中间封装方法很简单,所以就很简单的掠过了
    步骤基本为:1.数据库提取数据转为已实例化的对象。
    2.将实例化的对象,存索引。此处,是一个字段即为一个Field .基本为:document.add(new StringField(“这里实例化对象的属性(即字段名)”, “字段值”, Store.YES));这里的StringField,即在新版LUC内是只存储不对其分词但将其作为索引的建立索引方式。而TextField则是存储索引,且对其分词且索引。还有StoreField则是只存储不索引不分词。
    3.写提交indexWriter每1000次提交一次。
    先上代码。(很抱歉不大会用这个写博客,就先这么写上了。改天再研究)

    /**
         * 循环多线程创建索引
         */
        @Override
        public void CreateIndexFullSearch() {
            ExecutorService executor = Executors.newCachedThreadPool();
            // 获得所有源表名
            Set<String> tableSourceList = FieldsTranslator.signInfoMap.keySet();
         //因为此处是自己创建的一个翻译类内的内容,MAp(“数据库内的表名(也可以称之为数据库转存对象的对象名)”,“中文翻译,例如基本信息”)
         //此处的遍历循环创建索引,采用线程池,加快其建立索引的速度。
            for (String tablename : tableSourceList) {
                CreateIndexSearch myThread = new CreateIndexSearch(tablename);
                executor.execute(myThread);
            }
            executor.shutdown();
        }
    
    
        public class CreateIndexSearch extends Thread {
    //因为在创建所以的时候需要传表名来获取该表内容的存储位置及该表内字段,但在线程重写的Run方法内是无参的,所以我们需要在内部类创建的时候就传入这个在内部可调用的参。
            private String tableSource;
            /**
             * @param tableSoure
             */
            public CreateIndexSearch(String tableSource) {
                super();
                this.tableSource = tableSource;
            }
            /**
             * @return the tableSource
             */
            public String getTableSource() {
                return tableSource;
            }
            /**
             * @param tableSource
             *            the tableSource to set
             */
            public void setTableSource(String tableSource) {
                this.tableSource = tableSource;
            }
    //上面这部分的构造其实只要有类构造方法就行,但下部的G/S方法涉及到下面的值获取。
            /**
             * 用于创建给定来源表的索引
             * 
             * @param tableSource
             * @throws IOException
             */
            public void run() {
                // 存放路径 此处的存放路径也保存在翻译类的静态map,需要通过表名去获取到这个地址。
                String INDEX_DIR = FieldsTranslator.IndexDirMap.get(tableSource);(“D://Lucnen/不同的表有不同的存储位置”)在不同的分布上采用不同的获取。
                // 分词器 选择IK分词器 中文分词一般更偏向ANSJ,但ANS级对含英文的数字串符的分词对项目而言并不理想。所以在实验了多个分词器后,IK虽然对名字的分词超乎我想象的渣,但正向最大切分还是比较适合项目。
                IKAnalyzer analyzerT = new IKAnalyzer(true);
                // 表内数据  这里是一个封装的方法,旨在获取表内数据的List,这个List一般形式为List<obj> 
                List<?> indexList = getIndexList(tableSource);
                // 表内字段 也是方法,其实是从静态map<"字段名(name)","字段名的中文(姓名)">获取到字段的名字。
                Set<String> propertyName = getpropertyName(tableSource);
                // 标记字段 这是我用来获取表名的翻译maP<"表名(User)","表的中文(用户表)">
                String signInfo = FieldsTranslator.signInfoMap.get(tableSource);
                Directory dir = null;
                try {
                    dir = FSDirectory.open(new File(INDEX_DIR));
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_47,
                        analyzerT);
                IndexWriter indexWriter = null;
                try {
                    indexWriter = new IndexWriter(dir, config);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                for (int i = 0; i < indexList.size(); i++) {
                    Document document = new Document();
                    document.add(new StringField("归属类", tableSource, Store.YES));
                    document.add(new TextField("标注", signInfo, Store.YES));
                    for (String key : propertyName) {
                        // 判断该搜索域是否需要索引,默认不索引 
                        if (getsearchRegion(key)) {
    //这里的这个是翻译类,就是你表内存的数据可能用一些英文或者数字来标记,比如0和1来表示男和女,这里是将它们转为中文。
                            // 修改需要索引的就诊类型的表达字符,将该值改为汉字表达
                            String Str = getFieldValueByName(key, indexList.get(i))
                                    .replaceAll(" ", "");
                            document.add(new StringField(key, ValueTranslator
                                    .TranslterStr(key, Str), Store.YES));
                        } else {
                            // 修改需要索引的就诊类型的表达字符,将该值改为汉字表达
                            String Str = getFieldValueByName(key, indexList.get(i))
                                    .replaceAll(" ", "");
                            document.add(new TextField(key, ValueTranslator
                                    .TranslterStr(key, Str), Store.YES));
                        }
                    }
                    try {
                        indexWriter.addDocument(document);
    //这里其实是利用IndexWrite的锁机制,让他开闭锁的频率变为每1000个Doc再上提。
                        if (i % 1000 == 0) {
                            indexWriter.commit();
                        }
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
    
    
                }
                try {
                    indexWriter.commit();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                try {
                    log.info(signInfo + "索引文件创建完毕!");
                    indexWriter.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    
    
            /**
             * 该方法用以获取表内信息并输出
             * 
             * @param tableSource来源表名
             */
            private List<?> getIndexList(String tableSource) {
                List<?> indexList = new ArrayList<>();
                switch (tableSource) {
                case "ClinicalDocumentVo":
                    // 临床信息表内数据
                    indexList = createIndexClinicalDocumentVoDao
                            .getClinicalDocumentVo();
                    break;
                        ****省略
                case "PatientInspectionVoB":
                    // 影像表内数据
                    indexList = createIndexVoBDao.getPatientInspectionVoB();
                    break;
    
                default:
                    log.info("获取" + tableSource + "表内数据时失败,请检查。");
                    break;
                }
                return indexList;
            }
    
    
            /**
             * 私有方法:用于通过属性得到属性值
             * 自己写着玩的一个方法,实例化的一个对象,通过对象属性来获取到这个对象的属性值
             * @param fieldName
             * @param o
             * @return
             */
            private String getFieldValueByName(String fieldName《属性名》, Object o《对象名》) {
                String firstLetter = fieldName.substring(0, 1).toUpperCase();
                String getter = "get" + firstLetter + fieldName.substring(1);
                Method method = null;
                try {
                    method = o.getClass().getMethod(getter, new Class[] {});
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (SecurityException e) {
                    e.printStackTrace();
                }
                Object value = null;
                try {
                    if (method != null) {
                        value = method.invoke(o, new Object[] {});
                    } else {
                        log.info("通过属性名获取属性值时发生错误");
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
                return value + "";
            }
    
    
            /**
             * 该方法用于获取表内字段
             *这方法就   ****略
             * @param tableSource
             * @return
             */
    
    
            /**
             * 判断该域是否需要只存储不索引
             * 略****
             * @param
             * @return
             */
            ******
        }

    创建索引就差不多这个样子。上面我注释大概应该算作很详细了。
    下面是索引的搜索部分。

         public ScoreDoc[] FullSearchAll(String text) throws IOException,
                ParseException {
            ScoreDoc[] hitAll = null;
            IKAnalyzer analyzerT = new IKAnalyzer(true);
            // 此处域项暂未添加更多功能 因为索引存在不同的域 我们使用multiReader来同步读取  此处类似分布式索引。
    /*confirmRegion(“”);这个方法就是传出一个打开所有DIR的readerj集合   我在想法曝出,只是因为太多所以就重写了*/
            IndexReader[] reader = confirmRegion(“”);
    //MultiReader 其实以前常用的一般是MultiSearch 自带线程的p**MultiSearch(忘了叫啥来着,请自行百度),但是4.0之后就被干掉了。不过这里的MultiReader其实在速度上得到了很大提升,在处理千万级别索引时,查询速度大概在1秒不到这个样子。这里的分布读取是我需要的。
            MultiReader multiReader = new MultiReader(reader);
            String[] searchRegion = getsearchRegion();
            IndexSearcher isearcher = new IndexSearcher(multiReader);
    //这里的Search其实也有很多,只是比较Luc近期的方法,感觉IndexSearch更适合。
    //这里是多字段多内容的联合查找方式。 
            MultiFieldQueryParser parser = new MultiFieldQueryParser(
                    Version.LUCENE_47, searchRegion, analyzerT);
    //原先是准备在这边运用booleanQuery等不同类型的Query做一个不同程度的索引 ,其实也是已经作出了包括OCCMust及OCCShould等方式的维度查询,还有RangeQuery的时间节点筛选和值筛。但都被客户一句话干掉了(哦发火 谢特) 然后这里就是阉割版的。
            Query queryShould = parser.parse(text.replaceAll("[\\pZ]|[\\pP]", ""));
            hitAll = isearcher.search(queryShould, null, 1000).scoreDocs;
            return hitAll;
        }
    
    
        /**
         * 优先匹配基本信息的全文检索
         * 
         * @param 关键字
         *            页码 每页显示数目
         */
        @SuppressWarnings("unchecked")
        public List<FullSearchInfo> FullSearch(String text, String pageNum,
                String pageSize) throws IOException, ParseException {
            List<FullSearchInfo> tableinfo = new ArrayList<FullSearchInfo>();
            IndexReader[] reader = confirmRegion(allPath);
            MultiReader multiReader = new MultiReader(reader);
            IndexSearcher isearcher = new IndexSearcher(multiReader);
            ScoreDoc[] b = FullSearchAll(text);
            ScoreDoc[] hitAll = null;
            hitAll = b;
            // 查询分页 分页这部分其实我并不喜欢整在外头,但是,客户说,我这一段太长了。你特么闲着没事看啥源码? 出于。。。。我在获取查询总条数时加了一个浪费小效率的二次查询的小改动。等二版改效率再见。
            int start = (Integer.parseInt(pageNum) - 1)
                    * Integer.parseInt(pageSize);
            int end = Integer.parseInt(pageNum) * Integer.parseInt(pageSize);
            for (int i = start; i < end; i++) {
            *******后台输出****因为涉及到部分东西,然后就不显示了。
        }

    以上,其实已经差不多了吧?
    嗯,其实Luc经过这么多次改版,其方法改变了很多,也是花了几个晚上统统试了一遍,当然也有部分方法看着API都没能搞掂,也是醉的不行。
    可能理解有些浅显,一想对初学的人可以是一个小参考。所以还是写了,当然,相较于打字更喜欢动笔的我写的很少,不懂就私信吧。
    QS568356@163.com 回复邮件分时间。着急可以红名

    更多相关内容
  • 创建索引的注意事项

    千次阅读 2022-04-21 17:15:36
    .11种适合创建索引的常见情况 1. 字段的数值有唯一性的限制 业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。(来源:Alibaba) 说明:不要以为唯一索引影响了 insert 速度,这个速度损耗可以...

    目录

    一.11种适合创建索引的常见情况

    1. 字段的数值有唯一性的限制

    2. 频繁作为 WHERE 查询条件的字段

    3. 经常 GROUP BY 和 ORDER BY 的列

    4. UPDATE、DELETE 的 WHERE 条件列

    5.DISTINCT 字段需要创建索引

    6. 多表 JOIN 连接操作时,创建索引注意事项

    7. 使用列的类型小的创建索引

    8. 使用字符串前缀创建索引

    9. 区分度高(散列性高)的列适合作为索引

    10. 使用最频繁的列放到联合索引的左侧

    11. 在多个字段都要创建索引的情况下,联合索引优于单值索引

    二.7种不适合创建索引的常见情况

    1. 在where中使用不到的字段,不要设置索引

    2. 数据量小的表最好不要使用索引

    3. 有大量重复数据的列上不要建立索引

    4. 避免对经常更新的表创建过多的索引

    5. 不建议用无序的值作为索引

    6. 删除不再使用或者很少使用的索引

    7. 不要定义冗余或重复的索引

    ① 冗余索引

    ② 重复索引

    特别鸣谢:


    一.11种适合创建索引的常见情况

    1. 字段的数值有唯一性的限制

    业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。(来源:Alibaba)

    说明:不要以为唯一索引影响了 insert 速度,这个速度损耗可以忽略,但提高查找速度是明显的。

    2. 频繁作为 WHERE 查询条件的字段

            某个字段在SELECT语句的 WHERE 条件中经常被使用到,那么就需要给这个字段创建索引了。尤其是在数据量大的情况下,创建普通索引就可以大幅提升数据查询的效率。

    比如学生表数据表(含100万条数据),我们肯定会经常用到学生的学号和姓名等。

    3. 经常 GROUP BY ORDER BY 的列

            索引就是让数据按照某种顺序进行存储或检索,因此当我们使用 GROUP BY 对数据进行分组查询,或者使用ORDER BY对数据进行排序的时候,就需要对分组或者排序的字段进行索引 。如果待排序的列有多个,那么可以在这些列上建立组合索引

    4. UPDATE、DELETE WHERE 条件列

            对数据按照某个条件进行查询后再进行 UPDATE 或 DELETE 的操作,如果对 WHERE 字段创建了索引,就能大幅提升效率。原理是因为我们需要先根据 WHERE 条件列检索出来这条记录,然后再对它进行更新或删除。

    小提示:如果进行更新的时候,更新的字段是非索引字段,提升的效率会更明显,这是因为非索引字段更新不需要对索引进行维护。

    5.DISTINCT 字段需要创建索引

            有时候我们需要对某个字段进行去重,使用 DISTINCT,那么对这个字段创建索引,也会提升查询效率。这是因为索引会对数据按照某种顺序进行排序,所以在去重的时候也会快很多。

    6. 多表 JOIN 连接操作时,创建索引注意事项

            首先, 连接表的数量尽量不要超过 3 张 ,因为每增加一张表就相当于增加了一次嵌套的循环,数量级增长会非常快,严重影响查询的效率。其次, 对 WHERE 条件创建索引 ,因为 WHERE 才是对数据条件的过滤。如果在数据量非常大的情况下,没有 WHERE 条件过滤是非常可怕的。

            最后, 对用于连接的字段创建索引 ,并且该字段在多张表中的 类型必须一致 。比如 course_id 在student_info 表和 course 表中都为 int(11) 类型,而不能一个为 int 另一个为 varchar 类型,因为类型不一样时数据库是会做隐式类型转换的,而做了类型转换的sql是不走索引的。

    7. 使用列的类型小的创建索引

            我们这里所的类型大小指的就是该类型表示的数据范围的大小。 我们在定义表结构的时候要显式的指定列的类型, 以整数类型为例, 有TINYINT 、INT , BIGINT 等, 它们占用的存储空间依次递增, 能表示的整数范围当然也是依次递增。如果我们想要对某个整数列 建立索引的时,在表示的整数范围允许的情况下, 尽量让索引列使用较小的类型, 比如我们能使INT 就不要使 BIGINT。这是因为:

    • 数据类型越小,在查询时进行的交操作越快
    • 数据类型越小,索引占用的存储空间就越少, 在一个数据页内就可以放下更多的记录, 从而减少磁I/0 带 来的性能损耗,也就意味着可以把更多的数据页缓存在内存中, 从而加快读写效率。

    这个建议对于表的主键来说更加适用, 因为不仅是聚簇索引中会存储主键值, 其他所有的二级索引的节点处都会存储一份记录的主键值, 如果主诞使甲更小的数据类型, 也就意味着节省更多的存储空间和更高效的。

    8. 使用字符串前缀创建索引

    拓展: Alibaba 《Java 开发手册》
    强制 】在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度。
     说明:索引的长度与区分度是一对矛盾体,一般对字符串类型数据,长度为 20 的索引,区分度会 高达90% 以上 ,可以使用 count(distinct left( 列名 , 索引长度 ))/count(*) 的区分度来确定。

    9. 区分度高(散列性高)的列适合作为索引

    10. 使用最频繁的列放到联合索引的左侧

    这样也可以较少的建立一些索引。同时,由于"最左前缀原则",可以增加联合索引的使用率。

    11. 在多个字段都要创建索引的情况下,联合索引优于单值索引

    二.7种不适合创建索引的常见情况

    1. 在where中使用不到的字段,不要设置索引

    2. 数据量小的表最好不要使用索引

    3. 有大量重复数据的列上不要建立索引

    举例1:要在 100 万行数据中查找其中的 50 万行(比如性别为男的数据),一旦创建了索引,你需要先访问 50 万次索引,然后再访问 50 万次数据表,这样加起来的开销比不使用索引可能还要大。

    结论:当数据重复度大(比如 高于 10% 的时候),也不需要对这个字段使用索引。

    4. 避免对经常更新的表创建过多的索引

    5. 不建议用无序的值作为索引

    例如身份证、UUID(在索引比较时需要转为ASCII,并且插入时可能造成页分裂)、MD5、HASH、无序长字符串等。

    6. 删除不再使用或者很少使用的索引

    7. 不要定义冗余或重复的索引

    ① 冗余索引

    举例:建表语句如下
    CREATE TABLE person_info(
    id INT UNSIGNED NOT NULL AUTO_INCREMENT ,
    name VARCHAR ( 100 ) NOT NULL ,
    birthday DATE NOT NULL ,
    phone_number CHAR ( 11 ) NOT NULL ,
    country varchar ( 100 ) NOT NULL ,
    PRIMARY KEY (id),
    KEY idx_name_birthday_phone_number (name( 10 ), birthday, phone_number),
    KEY idx_name (name( 10 ))
    );
    通过 idx_name_birthday_phone_number 索引就可以对 name 列进行快速搜索,再创建一 个专门针对 name 列的索引就算是一个 冗余索引 ,维护这个索引只会增加维护的成本,并不会对搜索有什么好处。

    ② 重复索引

    另一种情况,我们可能会对某个列 重复建立索引 ,比方说这样:
    CREATE TABLE repeat_index_demo (
    col1 INT PRIMARY KEY ,
    col2 INT ,
    UNIQUE uk_idx_c1 (col1),
    INDEX idx_c1 (col1)
    )
    我们看到, col1 既是主键、又给它定义为一个唯一索引,还给它定义了一个普通索引,可是主键本身就会生成聚簇索引,所以定义的唯一索引和普通索引是重复的,这种情况要避免。

    最后敲黑板:“限制索引的数目

    特别鸣谢:

    以上知识来源于“尚硅谷”,宋红康老师的《MySQL数据库教程天花板,mysql安装到mysql高级,强!硬!》系列课程。

    所以本文章看不懂的卷王们可以去搜索宋红康老师的mysql系列课程。

    展开全文
  • ElasticSearch学习笔记 Elasticsearch学习笔记() Elasticsearch是个分布式的、RESTful风格的搜索和数据分析引擎。 安装Elasticsearch 安装Elasticsearch,这里选择在Windows...进入到bin目录打开elasticsearch.ba

    ElasticSearch学习笔记

    Elasticsearch学习笔记(一)

    Elasticsearch是一个分布式的、RESTful风格的搜索和数据分析引擎。

    安装Elasticsearch

    安装Elasticsearch,这里选择在Windows电脑中安装。[Elasticsearch官网Windows下载地址](Past Releases of Elastic Stack Software | Elastic)

    下载完之后打开解压文件,进入文件夹

    image-20211108104525457

    进入到bin目录打开elasticsearch.bat文件,就可以启动Elasticsearch。

    image-20211108104549453

    启动之后可以通过localhost:9200访问,查看测试结果

    image-20211108105550418

    Restful风格

    REST指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是RESTful。REST表象化状态转变(表述性状态转变),基于HTTP、URI、XML、JSON等标准和协议,支持轻量级、跨平台、跨语言的架构设计。是Web服务的一种新的架构风格(一种思想)。在REST样式的Web服务中,每个资源都有一个地址。资源本身都是方法调用的目标,方法列表对所有资源都是一样的。

    RESTful架构的主要原则

    • 对网络上所欲的资源都有一个资源标识符
    • 对资源的操作不会改变标识符。
    • 同一资源有多种表现形式(xml、json)
    • 所有操作都是无状态的(Stateless)

    符合上述REST原则的架构方式称为RESTful

    安装Postman

    为了方便进行客户端的访问,使用Postman软件。

    Postman是一款强大的页面调试工具,提供功能强大的WebAPI和HTTP请求调试。软件功能强大,界面简洁清晰,操作方便快捷。

    Postman官网

    Elasticsearch数据格式

    Elasticsearch是面向文档型数据库,一条数据就是一个文档。下面是Elasticsearch存储文档数据和MySQL存储数据的一个比较。

    image-20211108134501296

    ES中的Index可以看成一个库,Types相当于表,Documents相当于表的行。在Elasticsearch 7.x中,Type的概念已经被删除了,就是一个索引下面只能有一种类型。

    ES中的_doc是什么意思

    _ doc就代表映射类型,Elasticsearch 7.x中一个索引中只能有一个type,因此_ doc就代表该类型,所以你会发现在想索引中添加文档时使用_ doc添加后,再在该索引下添加文档使用food,查询时,类型全为food。

    索引操作

    1)创建索引

    在Elasticsearch中创建索引就等同于创建数据库

    向ES服务器发出PUT方式的请求:localhost:9200/shopping,就是创建索引。

    image-20211108162942308

    如果重复添加索引会返回错误信息。

    2)查看所有的索引

    向ES服务器发送GET请求:localhost:9200/_cat/indices?v

    _cat 表示查看的意思,indices表示索引

    image-20211108163105248

    • health:表示当前服务器状态:green(集群完整)yellow(单点正常、集群不完整)red(单点不正常)
    • status:索引打开关闭状态
    • index:索引名
    • uuid:索引统一编号
    • pri:主分片数量
    • rep:副本数量
    • docs.count:可用文档数量
    • docs.deleted:文档删除状态(逻辑删除)
    • store.size:主分片和副分片整体占空间大小
    • pri.store.size:主分片占空间大小

    3)查看单个索引

    向ES服务器发送GET请求:localhost:9200/shopping

    image-20211108163718526

    4)删除索引

    向ES服务器发送DELETE请求:localhost:9200/shopping

    image-20211108163941756

    删除之后再查看会返回索引不存在的信息

    image-20211108164120065

    文档操作

    1)创建文档

    索引已经创建好了接下来就可以创建文档,并添加数据了。文档就相当于关系型数据库中的表数据,添加的数据格式为JSON格式。

    向ES服务器发送POST请求:localhost:9200:/shopping/_doc,同时需要加上请求体:

    {"title": "面包",
    "price": 10
    }
    

    发送请求的方式必须为POST,不能是PUT,否则会返回错误信息

    image-20211108164625495

    在创建数据时,没有指定数据唯一性标识(ID),索引,默认的ES服务器会随机生成一个。

    也可以自定义唯一性标识,即在创建时指定

    localhost:9200/shopping/_doc/1001

    image-20211108165233583

    2)查看文档

    查看文档时,需要指明文档的唯一性标识

    向ES服务器发送GET请求:localhost:9200/shopping/food/1

    image-20211108170643641

    查看索引所有数据

    向ES服务器发送GET请求:localhost:9200/shopping_search

    image-20211108175043825

    3)修改文档

    和新增文档一样,需要修改时,在请求体中修改字段同时请求方式可以为PUT和POST请求。

    向ES服务器发送PUT,POST请求:localhost:9200/shopping/food/1001

    同时在请求体中修改字段:

    {
        "title": "西游记",
        "price": 23
    }
    

    image-20211108171912997

    其中version为版本号。

    4)修改字段

    ​ 向ES服务器发送POST请求:localhost:9200/shopping/_update/1001

    同时请求体内容为:

    {
        "doc":{
            "title":"甜甜圈11"
        }
    }
    

    image-20211108174111477

    5)删除文档

    向ES服务器发送DELETE请求:localhost:9200/shopping/_doc/1002

    删除文档不会立即从磁盘中删除,只是先将该文档标记为删除。

    image-20211108174425560

    6)条件删除文档

    还可以根据条件对多条文档数据进行删除

    向ES服务器发送PSOT请求:localhost:9200/shopping/_delete_by_query

    image-20211108175532415

    其中相应数据中的took字段代表耗时。

    还可以通过请求体条件进行查询

    {
        "query":{
            "match":{
                "title":"西游记"
            }
        }
    }
    

    image-20211109093443175

    展开全文
  • SQL Server 创建索引(index)

    千次阅读 多人点赞 2019-06-14 18:01:13
    索引分为聚集索引和非聚集索引,数据库中的索引类似于本书的目录,在本书中通过目录可以快速找到你想要的信息,而不需要读完全书。 索引主要目的是提高了SQLServer系统的性能,加快数据的查询速度与减少系统的...

    索引的简介:

    create index 索引名称 on 表名称(字段名称)

    索引分为聚集索引和非聚集索引,数据库中的索引类似于一本书的目录,在一本书中通过目录可以快速找到你想要的信息,而不需要读完全书。

    索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间 。

    但是索引对于提高查询性能也不是万能的,也不是建立越多的索引就越好。索引建少了,用 WHERE 子句找数据效率低,不利于查找数据。索引建多了,不利于新增、修改和删除等操作,因为做这些操作时,SQL SERVER 除了要更新数据表本身,还要连带立即更新所有的相关索引,而且过多的索引也会浪费硬盘空间。

     

    索引的分类:

    索引就类似于中文字典前面的目录,按照拼音或部首都可以很快的定位到所要查找的字。

    唯一索引(UNIQUE):每一行的索引值都是唯一的(创建了唯一约束,系统将自动创建唯一索引)

    主键索引:当创建表时指定的主键列,会自动创建主键索引,并且拥有唯一的特性。

    聚集索引(CLUSTERED):聚集索引就相当于使用字典的拼音查找,因为聚集索引存储记录是物理上连续存在的,即拼音 a 过了后面肯定是 b 一样。

    非聚集索引(NONCLUSTERED):非聚集索引就相当于使用字典的部首查找,非聚集索引是逻辑上的连续,物理存储并不连续。

    PS:聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个。

     

    什么情况下使用索引:

    语法:

    CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name   
        ON <object> ( column_name [ ASC | DESC ] [ ,...n ] )   
        [ WITH <backward_compatible_index_option> [ ,...n ] ]  
        [ ON { filegroup_name | "default" } ]  
      
    <object> ::=  
    {  
        [ database_name. [ owner_name ] . | owner_name. ]   
        table_or_view_name  
    }  
      
    <backward_compatible_index_option> ::=  
    {   
        PAD_INDEX  
      | FILLFACTOR = fillfactor  
      | SORT_IN_TEMPDB  
      | IGNORE_DUP_KEY  
      | STATISTICS_NORECOMPUTE   
      | DROP_EXISTING   
    }

    参数:

    UNIQUE:为表或视图创建唯一索引。 唯一索引不允许两行具有相同的索引键值。 视图的聚集索引必须唯一。如果要建唯一索引的列有重复值,必须先删除重复值。

    CLUSTERED:表示指定创建的索引为聚集索引。创建索引时,键值的逻辑顺序决定表中对应行的物理顺序。 聚集索引的底层(或称叶级别)包含该表的实际数据行。

    NONCLUSTERED:表示指定创建的索引为非聚集索引。创建一个指定表的逻辑排序的索引。 对于非聚集索引,数据行的物理排序独立于索引排序。

    index_name:表示指定所创建的索引的名称。

    database_name:表示指定的数据库的名称。

    owner_name:表示指定所有者。

    table:表示指定创建索引的表的名称。

    view:表示指定创建索引的视图的名称。

    column:索引所基于的一列或多列。 指定两个或多个列名,可为指定列的组合值创建组合索引。

    [ ASC | DESC]:表示指定特定索引列的升序或降序排序方向。 默认值为 ASC。

    on filegroup_name:为指定文件组创建指定索引。 如果未指定位置且表或视图尚未分区,则索引将与基础表或视图使用相同的文件组。 该文件组必须已存在。

    on default:为默认文件组创建指定索引。

    PAD_INDEX = {ON |OFF }:指定是否索引填充。默认为 OFF。

      ON 通过指定的可用空间的百分比fillfactor应用于索引中间级别页。

      OFF 或 fillfactor 未指定,考虑到中间级页上的键集,将中间级页填充到接近其容量的程度,以留出足够的空间,使之至少能够容纳索引的最大的一行。

      PAD_INDEX 选项只有在指定了 FILLFACTOR 时才有用,因为 PAD_INDEX 使用由 FILLFACTOR 指定的百分比。

    FILLFACTOR = fillfactor:用于指定在创建索引时,每个索引页的数据占索引页大小的百分比,fillfactor 的值为1到100。

    SORT_IN_TEMPDB = {ON |OFF }:用于指定创建索引时的中间排序结果将存储在 tempdb 数据库中。 默认为 OFF。

      ON 用于生成索引的中间排序结果存储在tempdb。 这可能会降低仅当创建索引所需的时间tempdb位于不同的与用户数据库的磁盘集。 

      OFF 中间排序结果与索引存储在同一数据库中。

    IGNORE_DUP_KEY = {ON |OFF }:指定在插入操作尝试向唯一索引插入重复键值时的错误响应。默认为 OFF。

      ON 向唯一索引插入重复键值时将出现警告消息。 只有违反唯一性约束的行才会失败。

      OFF 向唯一索引插入重复键值时将出现错误消息。 整个 INSERT 操作将被回滚。

    STATISTICS_NORECOMPUTE = {ON |OFF}:用于指定过期的索引统计是否自动重新计算。 默认为 OFF。

      ON 不会自动重新计算过时的统计信息。

      OFF 启用统计信息自动更新功能。

    DROP_EXISTING = {ON |OFF }:表示如果这个索引还在表上就 drop 掉然后在 create 一个新的。 默认为 OFF。

      ON 指定要删除并重新生成现有索引,其必须具有相同名称作为参数 index_name。

      OFF 指定不删除和重新生成现有的索引。 如果指定的索引名称已经存在,SQL Server 将显示一个错误。

    ONLINE = {ON |OFF}:表示建立索引时是否允许正常访问,即是否对表进行锁定。默认为 OFF。

      ON 它将强制表对于一般的访问保持有效,并且不创建任何阻止用户使用索引和/表的锁。

      OFF 对索引操作将对表进行表锁,以便对表进行完全和有效的访问。

    例子:

    创建唯一聚集索引:

    -- 创建唯一聚集索引
    create unique clustered        --表示创建唯一聚集索引
    index UQ_Clu_StuNo        --索引名称
    on Student(S_StuNo)        --数据表名称(建立索引的列名)
    with 
    (
        pad_index=on,    --表示使用填充
        fillfactor=50,    --表示填充因子为50%
        ignore_dup_key=on,    --表示向唯一索引插入重复值会忽略重复值
        statistics_norecompute=off    --表示启用统计信息自动更新功能
    )

    创建唯一非聚集索引:

    -- 创建唯一非聚集索引
    create unique nonclustered        --表示创建唯一非聚集索引
    index UQ_NonClu_StuNo        --索引名称
    on Student(S_StuNo)        --数据表名称(建立索引的列名)
    with 
    (
        pad_index=on,    --表示使用填充
        fillfactor=50,    --表示填充因子为50%
        ignore_dup_key=on,    --表示向唯一索引插入重复值会忽略重复值
        statistics_norecompute=off    --表示启用统计信息自动更新功能
    )
    --创建聚集索引
    create clustered index Clu_Index
    on Student(S_StuNo)
    with (drop_existing=on)    
    
    --创建非聚集索引
    create nonclustered index NonClu_Index
    on Student(S_StuNo)
    with (drop_existing=on)    
    
    --创建唯一索引
    create unique index NonClu_Index
    on Student(S_StuNo)
    with (drop_existing=on)

    PS:当 create index 时,如果未指定 clustered 和 nonclustered,那么默认为 nonclustered。

    创建非聚集复合索引:

    --创建非聚集复合索引
    create nonclustered index Index_StuNo_SName
    on Student(S_StuNo,S_Name)
    with(drop_existing=on)
    --创建非聚集复合索引,未指定默认为非聚集索引
    create index Index_StuNo_SName
    on Student(S_StuNo,S_Name)
    with(drop_existing=on)

    在 CREATE INDEX 语句中使用 INCLUDE 子句,可以在创建索引时定义包含的非键列(即覆盖索引),其语法结构如下:

    CREATE NONCLUSTERED INDEX 索引名
    ON { 表名| 视图名 } ( 列名 [ ASC | DESC ] [ ,...n ] )
    INCLUDE (<列名1>, <列名2>, [,… n])
    
    
    --创建非聚集覆盖索引
    create nonclustered index NonClu_Index
    on Student(S_StuNo)
    include (S_Name,S_Height)
    with(drop_existing=on)
    
    --创建非聚集覆盖索引,未指定默认为非聚集索引
    create index NonClu_Index
    on Student(S_StuNo)
    include (S_Name,S_Height)
    with(drop_existing=on)

    PS:聚集索引不能创建包含非键列的索引。

    创建筛选索引:

    --创建非聚集筛选索引
    create nonclustered index Index_StuNo_SName
    on Student(S_StuNo)
    where S_StuNo >= 001 and S_StuNo <= 020
    with(drop_existing=on)
    
    --创建非聚集筛选索引,未指定默认为非聚集索引
    create index Index_StuNo_SName
    on Student(S_StuNo)
    where S_StuNo >= 001 and S_StuNo <= 020
    with(drop_existing=on)

    修改索引:

    --修改索引语法
    ALTER INDEX { 索引名| ALL }
    ON <表名|视图名>
    { REBUILD  | DISABLE  | REORGANIZE }[ ; ]

    REBUILD:表示指定重新生成索引。

    DISABLE:表示指定将索引标记为已禁用。

    REORGANIZE:表示指定将重新组织的索引叶级。

    --禁用名为 NonClu_Index 的索引
    alter index NonClu_Index on Student disable

    删除和查看索引:

    --查看指定表 Student 中的索引
    exec sp_helpindex Student    
    
    --删除指定表 Student 中名为 Index_StuNo_SName 的索引
    drop index Student.Index_StuNo_SName
    
    --检查表 Student 中索引 UQ_S_StuNo 的碎片信息
    dbcc showcontig(Student,UQ_S_StuNo)
    
    --整理 Test 数据库中表 Student 的索引 UQ_S_StuNo 的碎片
    dbcc indexdefrag(Test,Student,UQ_S_StuNo)
    
    --更新表 Student 中的全部索引的统计信息
    update statistics Student

    索引定义原则:

    避免对经常更新的表进行过多的索引,并且索引中的列尽可能少。而对经常用于查询的字段应该创建索引,但要避免添加不必要的字段。

    在条件表达式中经常用到的、不同值较多的列上建立索引,在不同值少的列上不要建立索引。

    在频繁进行排序或分组(即进行 GROUP BY 或 ORDER BY 操作)的列上建立索引,如果待排序的列有多个,可以在这些列上建立组合索引。

    在选择索引键时,尽可能采用小数据类型的列作为键以使每个索引页能容纳尽可能多的索引键和指针,通过这种方式,可使一个查询必需遍历的索引页面降低到最小,此外,尽可能的使用整数做为键值,因为整数的访问速度最快。

     

    来源: https://www.cnblogs.com/jett010/p/9071030.html

     

    其他资料:

    聚集索引和非聚集索引(转)

     

    展开全文
  • 创建索引:4.1第种:界面上直接新建4.2第二种:postman种新建5.创建映射6.创建文档6.1 不指定ID,随机生成6.2 指定ID,推荐7.搜索文档8.IK分词器8.1 测试分词器8.2 安装IK分词器8.3 两种分词模式8.3.1 ik_max_word...
  • 如何创建高性能的索引

    千次阅读 2022-01-08 20:27:44
    如何创建高性能的索引 EXPLAIN 类型分析 explain 指令可以帮助我们查看查询优化器 处理 执行计划 的一些细节信息 语法: explain + 执行计划 假如我们有这样的两张表(分类表和商品表),我们将结合explain 字段...
  • SQL 创建索引,语法

    千次阅读 2014-06-07 16:10:16
    主键是唯一的,所以创建个主键的同时,也就这个字段创建个唯一的索引。SQL SERVER将主键默认定义为聚集索引,事实上,索引是否唯一与是否聚集是不相关的,聚集索引可以是唯一索引,也可以是非唯一索引; ...
  • word如何设置一级二级三级标题格式

    千次阅读 2021-06-11 14:53:45
    在Word中,可以自动生成目录,其具体的操作步骤:一、设置标题格式1、选中文章中的所有一级标题;2、单击开始选项卡上的标题1,如图所示;仿照步骤1、2设置二、三级标题格式为标题2、标题3。二、自动生成目录1、把...
  • 使用solr构建hbase二级索引

    千次阅读 2017-08-02 14:28:40
    使用solr构建hbase二级索引@(HBASE)[hbase, solr]使用solr构建hbase二级索引 概述 业务场景描述 二技术方案 1技术方案 2技术方案二 3关于索引的建议 二使用hbase-indexer构建hbase二级索引 安装环境准备 二...
  • MySQL中如何使用索引

    千次阅读 2021-01-15 12:03:56
    原标题:MySQL中如何使用索引 者:Airy 在数据分析之路狂奔,立志成为大咖人物。前言学完基础的MySQL知识,以及MySQL的增删改查,我们要学习一些性能方面的东西。今天来讲一下索引(Index)。索引在关系数据库中,...
  • Phoenix二级索引实战

    千次阅读 2022-01-30 16:29:30
    之前的查询,因为没有建立索引,组合条件查询效率较低,而通过使用Phoenix,我们可以非常方便地创建级索引。Phoenix中的索引,其实底层还是表现为HBase中的表结构。这些索引表专门用来加快查询速度。 索引分类 ...
  • 文章目录创建基本索引创建索引索引数据索引单个文档索引多个文档 创建基本索引 elasticsearch可以自动识别数据类型 本节的目的是将数据索引到elasticsearch中,没有使用mapping及analyzer等操作 后续会优先搜索部分...
  • 查看表中已经存在 index:showindex from table_name;创建和删除索引索引的创建可以在CREATE TABLE语句中进行,也可以单独用CREATE INDEX或...(1)使用ALTER TABLE语句创建索引。语法如下:alter table table_name ...
  • clickhouse之索引

    千次阅读 2021-07-31 22:31:40
    首先,clickhouse的一级索引使用了一种叫做稀疏索引的技术,那么何为稀疏索引呢?既然有稀疏索引,是不是相对的也有稠密索引呢?没错,确实有。二者的区别如下: 稠密索引: 每行数据记录都会对应一行索引标记。 ...
  • 复合索引: 多个列构成的索引,相当于二级目录 name,age 两个张三,再看年龄; 创建索引、create 索引类型 索引名 on 表 单值: create index dep_index on tb(dept); 唯一 create unique index...
  • Phoenix二级索引使用

    千次阅读 2019-05-23 14:57:56
    异步build索引需要借助MR,创建异步索引语法和同步索引相差个关键字:ASYNC。 创建异步索引 创建异步索引语法和同步索引相差个关键字:ASYNC。 CREATE INDEX ASYNC_IDX ON SCHEMA_NAME.TABLE_NAME...
  • MySQL高级篇——索引的数据结构

    千次阅读 多人点赞 2022-04-11 16:35:12
    文章目录: 1.为什么使用索引? 2.索引的优缺点 3.InnoDB中的索引 3.1 设计索引 3.2 常见索引概念 3.2.1 聚簇索引 3.2.2 非聚簇索引 3.2.3 联合索引 4.InnoDB与MyISAM的索引对比 5.B-Tree和B+Tree的差异 ...
  • 方法1、用WORD根据文章的章节自动生成目录--1.在[格式]中选[样式与格式]--2.出现右边的条“样式格式”栏,这里面主要就是用到标题1,标题2,标题3。把标题1,标题2,标题3分别应用到文中各个章节的标题上,设置...
  • Word中插入目录时未找到目录

    千次阅读 2013-12-23 09:50:13
    Word中插入目录时未找到目录
  • MySQL百万数据添加索引

    千次阅读 2019-01-07 19:52:14
    直接alter table add index 添加索引,执行个小时没反应,并且会导致锁表;故放弃该办法,最终解决办法如下: 解决方案 导出原表数据 创建新表与原表结构保持一致,在该表上执行alter语句添加索引; 将表数据...
  • confluence页面加目录索引

    万次阅读 2017-05-03 15:11:38
    先对索引项设置标题类型 再插入Table of Contents宏
  • 索引创建方式

    千次阅读 2018-07-03 19:34:22
    oracle的索引分为5种:唯一索引,组合索引,反向键索引,位图索引,基于函数的索引创建索引:CREATE [unique] INDEX index_name ON table (column)unique --唯一索引index_name --索引名称table --表名column (列.....
  • 索引分为聚集索引和非聚集索引,数据库中的索引类似于本书的目录,在本书中通过目录可以快速找到你想要的信息,而不需要读完全书。 索引主要目的是提高了SQLServer系统的性能,加快数据的查询速度与减少系统的...
  • 文件目录结构:单级、两、多级(树形)和无环图目录结构 与文件管理系统和文件集合相关联的是文件目录,它包含有关文件的信息,包括属性、 位置和所有权等,这些信息主要是由操作系统进行管理。首先我们来看目录...
  • 最近要搞个查询功能,是把hbase中的数据... 参考了网络上的设计,建立二级索引是比较好的思路.于是就以solr存储hbase里面的列索引,实现了这个功能. 需要的组件有: 1.hbase 2.solr 3.key-value store indexer ...
  • 使用索引也很简单,然而, 会使用索引回事, 而深入理解索引原理又能恰到好处使用索引又是另回事。 这已经是两个相差甚远的技术层级了。 二、千万数据表索引和无索引查询效率对比 现在有个学生表student,...
  • Phoenix 安装与使用(二级索引

    千次阅读 2020-08-13 11:44:13
    可以使用标准JDBC API代替HBase客户端API来创建表,插入数据和查询HBase数据。 Phoenix的团队用了句话概括Phoenix:"We put the SQL back in NoSQL" 意思是:我们把SQL又放回NoSQL去了!这边说的NoSQL专指HBase,...
  • 关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是辆兰博基尼的话,那么没有设计和使用索引的MySQL就是个人力三轮车。对于没有索引的表,单表查询可能几十万数据就是瓶颈,而通常大型网站单日就可能...
  • 大数据HBase(十二):Apache Phoenix 二级索引

    千次阅读 多人点赞 2021-07-18 10:03:59
    全网最详细的大数据HBase文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,...2、创建索引 3、查询数据 4、查询执行计划 5、删除索引 6、查看索引 7、测试查询所有列是否会使用索引 8、使用Hin.

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 164,989
精华内容 65,995
关键字:

创建索引目录时一级目录使用