精华内容
下载资源
问答
  • 基本使用创建节点,关系,查询) 详细使用,请参考w3school Neo4j教程 安装Neo4j Desktop 官网:https://neo4j.com/ 下载neo 4j 根据提示进行安装,运行出现如下界面,选择存放位置 出现...

    博客内容

    1. 安装Neo4j Desktop
    2. 基本使用(创建节点,关系,查询) 详细使用,请参考w3school Neo4j教程

    安装Neo4j Desktop

    官网:https://neo4j.com/

    1. 下载neo 4j
      在这里插入图片描述
      在这里插入图片描述

    2. 根据提示进行安装,运行出现如下界面,选择存放位置
      在这里插入图片描述

    3. 出现加载界面,等待结束,出现如下界面
      在这里插入图片描述

    neo4j 使用

    1. 创建图:

      选择 Add Graph
      

    接着,
    在这里插入图片描述
    接着,

    接着,
    在这里插入图片描述
    接着,
    在这里插入图片描述

    创建节点

    创建节点 输入create (dog:DOG{name:”小欢”,age:13}) 点击运行
    在这里插入图片描述

    查找节点

    查找节点 match(dog:DOG) return dog
    在这里插入图片描述

    多次创建节点,可以看到目前位置创建了6个节点:
    在这里插入图片描述

    创建关系:

    match (cat:CAT),(dog:DOG) create (dog)-[r:敌人] ->(cat)
    match (cat:CAT),(dog:DOG) create (cat)-[r:敌人] ->(dog)

    查找关系:

    如下操作,或者

    MATCH p=()-[r:敌人]->() RETURN p LIMIT 25

    继续创建关系。

    查询所有关系,固定用法

    MATCH p=()–>() RETURN p LIMIT 25
    在这里插入图片描述

    展开全文
  • 什么使用线程池;常见的创建线程池的4种方式

    万次阅读 多人点赞 2018-04-14 17:51:49
    1. 为什么使用线程池诸如 Web 服务器、数据库服务器、文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务。请求以某种方式到达服务器,这种方式可能是通过网络协议...

    1. 为什么使用线程池

    诸如 Web 服务器、数据库服务器、文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务。请求以某种方式到达服务器,这种方式可能是通过网络协议(例如 HTTPFTP 或 POP)、通过 JMS 队列或者可能通过轮询数据库。不管请求如何到达,服务器应用程序中经常出现的情况是:单个任务处理的时间很短而请求的数目却是巨大的。

    构建服务器应用程序的一个简单模型是:每当一个请求到达就创建一个新线程,然后在新线程中为请求服务。实际上对于原型开发这种方法工作得很好,但如果试图部署以这种方式运行的服务器应用程序,那么这种方法的严重不足就很明显。每个请求对应一个线程(thread-per-request)方法的不足之一是:为每个请求创建一个新线程的开销很大;为每个请求创建新线程的服务器在创建和销毁线程上花费的时间和消耗的系统资源要比花在处理实际的用户请求的时间和资源更多。

    除了创建和销毁线程的开销之外,活动的线程也消耗系统资源。在一个 JVM 里创建太多的线程可能会导致系统由于过度消耗内存而用完内存或切换过度。为了防止资源不足,服务器应用程序需要一些办法来限制任何给定时刻处理的请求数目。

    线程池为线程生命周期开销问题和资源不足问题提供了解决方案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使应用程序响应更快。而且,通过适当地调整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其它任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源不足。

    2. 使用线程池的风险

    虽然线程池是构建多线程应用程序的强大机制,但使用它并不是没有风险的。用线程池构建的应用程序容易遭受任何其它多线程应用程序容易遭受的所有并发风险,诸如同步错误和死锁,它还容易遭受特定于线程池的少数其它风险,诸如与池有关的死锁、资源不足和线程泄漏。

    2.1 死锁

    任何多线程应用程序都有死锁风险。当一组进程或线程中的每一个都在等待一个只有该组中另一个进程才能引起的事件时,我们就说这组进程或线程 死锁了。死锁的最简单情形是:线程 持有对象 的独占锁,并且在等待对象 的锁,而线程 持有对象 的独占锁,却在等待对象 的锁。除非有某种方法来打破对锁的等待(Java 锁定不支持这种方法),否则死锁的线程将永远等下去。

    虽然任何多线程程序中都有死锁的风险,但线程池却引入了另一种死锁可能,在那种情况下,所有池线程都在执行已阻塞的等待队列中另一任务的执行结果的任务,但这一任务却因为没有未被占用的线程而不能运行。当线程池被用来实现涉及许多交互对象的模拟,被模拟的对象可以相互发送查询,这些查询接下来作为排队的任务执行,查询对象又同步等待着响应时,会发生这种情况。

    2.2 资源不足

    线程池的一个优点在于:相对于其它替代调度机制(有些我们已经讨论过)而言,它们通常执行得很好。但只有恰当地调整了线程池大小时才是这样的。线程消耗包括内存和其它系统资源在内的大量资源。除了 Thread 对象所需的内存之外,每个线程都需要两个可能很大的执行调用堆栈。除此以外,JVM 可能会为每个 Java 线程创建一个本机线程,这些本机线程将消耗额外的系统资源。最后,虽然线程之间切换的调度开销很小,但如果有很多线程,环境切换也可能严重地影响程序的性能。

    如果线程池太大,那么被那些线程消耗的资源可能严重地影响系统性能。在线程之间进行切换将会浪费时间,而且使用超出比您实际需要的线程可能会引起资源匮乏问题,因为池线程正在消耗一些资源,而这些资源可能会被其它任务更有效地利用。除了线程自身所使用的资源以外,服务请求时所做的工作可能需要其它资源,例如 JDBC 连接、套接字或文件。这些也都是有限资源,有太多的并发请求也可能引起失效,例如不能分配 JDBC 连接。

    2.3 并发错误

    线程池和其它排队机制依靠使用 wait()  notify() 方法,这两个方法都难于使用。如果编码不正确,那么可能丢失通知,导致线程保持空闲状态,尽管队列中有工作要处理。使用这些方法时,必须格外小心。而最好使用现有的、已经知道能工作的实现,例如 util.concurrent 包。

    2.4 线程泄漏

    各种类型的线程池中一个严重的风险是线程泄漏,当从池中除去一个线程以执行一项任务,而在任务完成后该线程却没有返回池时,会发生这种情况。发生线程泄漏的一种情形出现在任务抛出一个 RuntimeException 或一个 Error 时。如果池类没有捕捉到它们,那么线程只会退出而线程池的大小将会永久减少一个。当这种情况发生的次数足够多时,线程池最终就为空,而且系统将停止,因为没有可用的线程来处理任务。

    有些任务可能会永远等待某些资源或来自用户的输入,而这些资源又不能保证变得可用,用户可能也已经回家了,诸如此类的任务会永久停止,而这些停止的任务也会引起和线程泄漏同样的问题。如果某个线程被这样一个任务永久地消耗着,那么它实际上就被从池除去了。对于这样的任务,应该要么只给予它们自己的线程,要么只让它们等待有限的时间。

    2.5 请求过载

    仅仅是请求就压垮了服务器,这种情况是可能的。在这种情形下,我们可能不想将每个到来的请求都排队到我们的工作队列,因为排在队列中等待执行的任务可能会消耗太多的系统资源并引起资源缺乏。在这种情形下决定如何做取决于您自己;在某些情况下,您可以简单地抛弃请求,依靠更高级别的协议稍后重试请求,您也可以用一个指出服务器暂时很忙的响应来拒绝请求。

    3. 有效使用线程池的准则

    只要您遵循几条简单的准则,线程池可以成为构建服务器应用程序的极其有效的方法:

    不要对那些同步等待其它任务结果的任务排队。这可能会导致上面所描述的那种形式的死锁,在那种死锁中,所有线程都被一些任务所占用,这些任务依次等待排队任务的结果,而这些任务又无法执行,因为所有的线程都很忙。

    在为时间可能很长的操作使用合用的线程时要小心。如果程序必须等待诸如 I/O 完成这样的某个资源,那么请指定最长的等待时间,以及随后是失效还是将任务重新排队以便稍后执行。这样做保证了:通过将某个线程释放给某个可能成功完成的任务,从而将最终取得某些进展。

    理解任务。要有效地调整线程池大小,您需要理解正在排队的任务以及它们正在做什么。它们是 CPU 限制的(CPU-bound)吗?它们是 I/O 限制的(I/O-bound)吗?您的答案将影响您如何调整应用程序。如果您有不同的任务类,这些类有着截然不同的特征,那么为不同任务类设置多个工作队列可能会有意义,这样可以相应地调整每个池。

    4. 线程池的大小设置

    调整线程池的大小基本上就是避免两类错误:线程太少或线程太多。幸运的是,对于大多数应用程序来说,太多和太少之间的余地相当宽。

    请回忆:在应用程序中使用线程有两个主要优点,尽管在等待诸如 I/O 的慢操作,但允许继续进行处理,并且可以利用多处理器。在运行于具有 个处理器机器上的计算限制的应用程序中,在线程数目接近 时添加额外的线程可能会改善总处理能力,而在线程数目超过 时添加额外的线程将不起作用。事实上,太多的线程甚至会降低性能,因为它会导致额外的环境切换开销。

    线程池的最佳大小取决于可用处理器的数目以及工作队列中的任务的性质。若在一个具有 N 个处理器的系统上只有一个工作队列,其中全部是计算性质的任务,在线程池具有 或 N+1 个线程时一般会获得最大的 CPU 利用率。

    对于那些可能需要等待 I/O 完成的任务(例如,从套接字读取 HTTP 请求的任务),需要让池的大小超过可用处理器的数目,因为并不是所有线程都一直在工作。通过使用概要分析,您可以估计某个典型请求的等待时间(WT)与服务时间(ST)之间的比例。如果我们将这一比例称之为 WT/ST,那么对于一个具有 个处理器的系统,需要设置大约 N*(1+WT/ST) 个线程来保持处理器得到充分利用。

    处理器利用率不是调整线程池大小过程中的唯一考虑事项。随着线程池的增长,您可能会碰到调度程序、可用内存方面的限制,或者其它系统资源方面的限制,例如套接字、打开的文件句柄或数据库连接等的数目。

    5. 常用的几种线程池

    5.1 newCachedThreadPool

    创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

    这种类型的线程池特点是:

    • 工作线程的创建数量几乎没有限制(其实也有限制的,数目为Interger. MAX_VALUE), 这样可灵活的往线程池中添加线程。
    • 如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。
    • 在使用CachedThreadPool时,一定要注意控制任务的数量,否则,由于大量线程同时运行,很有会造成系统瘫痪。

    示例代码如下:

    复制代码
     1 package test;
     2 import java.util.concurrent.ExecutorService;
     3 import java.util.concurrent.Executors;
     4 public class ThreadPoolExecutorTest {
     5  public static void main(String[] args) {
     6   ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
     7   for (int i = 0; i < 10; i++) {
     8    final int index = i;
     9    try {
    10     Thread.sleep(index * 1000);
    11    } catch (InterruptedException e) {
    12     e.printStackTrace();
    13    }
    14    cachedThreadPool.execute(new Runnable() {
    15     public void run() {
    16      System.out.println(index);
    17     }
    18    });
    19   }
    20  }
    21 }
    复制代码

    5.2 newFixedThreadPool

    创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。

    FixedThreadPool是一个典型且优秀的线程池,它具有线程池提高程序效率和节省创建线程时所耗的开销的优点。但是,在线程池空闲时,即线程池中没有可运行任务时,它不会释放工作线程,还会占用一定的系统资源。

    示例代码如下:

     

    复制代码
    package test;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    public class ThreadPoolExecutorTest {
     public static void main(String[] args) {
      ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
      for (int i = 0; i < 10; i++) {
       final int index = i;
       fixedThreadPool.execute(new Runnable() {
        public void run() {
         try {
          System.out.println(index);
          Thread.sleep(2000);
         } catch (InterruptedException e) {
          e.printStackTrace();
         }
        }
       });
      }
     }
    }
    复制代码

     

    因为线程池大小为3,每个任务输出indexsleep 2秒,所以每两秒打印3个数字。
    定长线程池的大小最好根据系统资源进行设置如Runtime.getRuntime().availableProcessors()。

     

    5.3 newSingleThreadExecutor

    创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO,优先级)执行。如果这个线程异常结束,会有另一个取代它,保证顺序执行。单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的

    示例代码如下:

     

    复制代码
    package test;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    public class ThreadPoolExecutorTest {
     public static void main(String[] args) {
      ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
      for (int i = 0; i < 10; i++) {
       final int index = i;
       singleThreadExecutor.execute(new Runnable() {
        public void run() {
         try {
          System.out.println(index);
          Thread.sleep(2000);
         } catch (InterruptedException e) {
          e.printStackTrace();
         }
        }
       });
      }
     }
    } 
    复制代码

     

    5.4 newScheduleThreadPool

    创建一个定长的线程池,而且支持定时的以及周期性的任务执行支持定时及周期性任务执行。

    延迟3秒执行延迟执行示例代码如下:

     

    复制代码
    package test;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    public class ThreadPoolExecutorTest {
     public static void main(String[] args) {
      ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
      scheduledThreadPool.schedule(new Runnable() {
       public void run() {
        System.out.println("delay 3 seconds");
       }
      }, 3, TimeUnit.SECONDS);
     }
    }
    复制代码

     

    表示延迟1秒后每3秒执行一次定期执行示例代码如下:

     

    复制代码
    package test;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    public class ThreadPoolExecutorTest {
     public static void main(String[] args) {
      ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
      scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
       public void run() {
        System.out.println("delay 1 seconds, and excute every 3 seconds");
       }
      }, 1, 3, TimeUnit.SECONDS);
     }
    }
    展开全文
  • MySQL索引的创建使用

    万次阅读 多人点赞 2018-08-06 18:49:59
    声明:本人主要简单示例MySQL中的单列索引、组合索引的创建使用。 索引的创建: 建表时创建: CREATE TABLE 表名( 字段名 数据类型 [完整性约束条件], ……, [UNIQUE | FULLTEXT | SPATIAL] INDEX | KEY ...

    索引有很多,且按不同的分类方式,又有很多种分类。不同的数据库,对索引的支持情况也不尽相同。

    声明:本人主要简单示例MySQL中的单列索引组合索引的创建与使用。


    索引的创建

    建表时创建

    CREATE TABLE 表名(

    字段名 数据类型 [完整性约束条件],

           ……,

    [UNIQUE | FULLTEXT | SPATIAL] INDEX | KEY

    [索引名](字段名1 [(长度)] [ASC | DESC]) [USING 索引方法]

    );

    说明:

    • UNIQUE:可选。表示索引为唯一性索引。
    • FULLTEXT:可选。表示索引为全文索引。
    • SPATIAL:可选。表示索引为空间索引。
    • INDEX和KEY:用于指定字段为索引,两者选择其中之一就可以了,作用是    一样的。
    • 索引名:可选。给创建的索引取一个新名称。
    • 字段名1:指定索引对应的字段的名称,该字段必须是前面定义好的字段。
    • 长度:可选。指索引的长度,必须是字符串类型才可以使用。
    • ASC:可选。表示升序排列。
    • DESC:可选。表示降序排列。

    注:索引方法默认使用B+TREE。

    单列索引(示例):

    CREATE TABLE projectfile (
    	id INT AUTO_INCREMENT COMMENT '附件id',
    	fileuploadercode VARCHAR(128) COMMENT '附件上传者code',
    	projectid INT COMMENT '项目id;此列受project表中的id列约束',
    	filename VARCHAR (512) COMMENT '附件名',
    	fileurl VARCHAR (512) COMMENT '附件下载地址',
    	filesize BIGINT COMMENT '附件大小,单位Byte',
    	-- 主键本身也是一种索引(注:也可以在上面的创建字段时使该字段主键自增)
            PRIMARY KEY (id),
    	-- 主外键约束(注:project表中的id字段约束了此表中的projectid字段)
    	FOREIGN KEY (projectid) REFERENCES project (id),
    	-- 给projectid字段创建了唯一索引(注:也可以在上面的创建字段时使用unique来创建唯一索引)
    	UNIQUE INDEX (projectid),
    	-- 给fileuploadercode字段创建普通索引
    	INDEX (fileuploadercode)
    	-- 指定使用INNODB存储引擎(该引擎支持事务)、utf8字符编码
    ) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT '项目附件表';

    注:这里只为示例如何创建索引,其他的合理性之类的先放一边。

    组合索引(示例):

    CREATE TABLE projectfile (
    	id INT AUTO_INCREMENT COMMENT '附件id',
    	fileuploadercode VARCHAR(128) COMMENT '附件上传者code',
    	projectid INT COMMENT '项目id;此列受project表中的id列约束',
    	filename VARCHAR (512) COMMENT '附件名',
    	fileurl VARCHAR (512) COMMENT '附件下载地址',
    	filesize BIGINT COMMENT '附件大小,单位Byte',
    	-- 主键本身也是一种索引(注:也可以在上面的创建字段时使该字段主键自增)
            PRIMARY KEY (id),
            -- 创建组合索引
    	INDEX (fileuploadercode,projectid)
    	-- 指定使用INNODB存储引擎(该引擎支持事务)、utf8字符编码
    ) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT '项目附件表';

    建表后创建

    ALTER TABLE 表名 ADD [UNIQUE | FULLTEXT | SPATIAL]  INDEX | KEY  [索引名] (字段名1 [(长度)] [ASC | DESC]) [USING 索引方法]

    CREATE  [UNIQUE | FULLTEXT | SPATIAL]  INDEX  索引名 ON  表名(字段名) [USING 索引方法]

    示例一:

    -- 假设建表时fileuploadercode字段没创建索引(注:同一个字段可以创建多个索引,但一般情况下意义不大)
    -- 给projectfile表中的fileuploadercode创建索引
    ALTER TABLE projectfile ADD UNIQUE INDEX (fileuploadercode);

    示例二:

    ALTER TABLE projectfile ADD INDEX (fileuploadercode, projectid);

    示例三:

    -- 将id列设置为主键
    ALTER TABLE index_demo ADD PRIMARY KEY(id) ;
    -- 将id列设置为自增
    ALTER TABLE index_demo MODIFY id INT auto_increment;  

    查看已创建的索引

    show index from 表名;

    提示:我们也可以直接使用工具查看

    示例:


    索引的删除

    DROP INDEX 索引名 ON 表名

    ALTER TABLE 表名 DROP INDEX 索引名

    示例一:

    drop index fileuploadercode1 on projectfile;

    示例二:

    alter table projectfile drop index s2123;

    查看SQL语句对索引的使用情况(即:查询SQL的查询执行计划QEP)

    在select语句前加上EXPLAIN即可。

    示例:

    EXPLAIN SELECT * FROM `index_demo` ii WHERE ii.e_name = 'Jane';

    分析该SQL的性能为:

    提示:我们也可以使用SQL工具查看,如:navicat中的“解释”选项即可查看。

    说明:

    id:SELECT识别符。这是SELECT的查询序列号。

    select_type:SELECT类型。

    1. SIMPLE: 简单SELECT(不使用UNION或子查询)
    2. PRIMARY: 最外面的SELECT
    3. UNION:UNION中的第二个或后面的SELECT语句
    4. DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询
    5. UNION RESULT:UNION的结果
    6. SUBQUERY:子查询中的第一个SELECT
    7. DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询
    8. DERIVED:导出表的SELECT(FROM子句的子查询)

    table:表名

    type:联接类型。是SQL性能的非常重要的一个指标,结果值从好到坏依次是:system > const > eq_ref > ref
                > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL。
                一般来说,得保证查询至少达到range级别。

    1. system:表仅有一行(=系统表)。这是const联接类型的一个特例。
    2. const:表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const用于用常数值比较PRIMARY KEY或UNIQUE索引的所有部分时。
    3. eq_ref:对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。它用在一个索引的所有部分被联接使用并且索引是UNIQUE或PRIMARY KEY。eq_ref可以用于使用= 操作符比较的带索引的列。比较值可以为常量或一个使用在该表前面所读取的表的列的表达式。
    4. ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。如果联接只使用键的最左边的前缀,或如果键不是UNIQUE或PRIMARY KEY(换句话说,如果联接不能基于关键字选择单个行的话),则使用ref。如果使用的键仅仅匹配少量行,该联接类型是不错的。ref可以用于使用=或<=>操作符的带索引的列。
    5. ref_or_null:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。在解决子查询中经常使用该联接类型的优化。
    6. index_merge:该联接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。
    7. unique_subquery:该类型替换了下面形式的IN子查询的ref:value IN (SELECT primary_key FROMsingle_table WHERE some_expr);unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。
    8. index_subquery:该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引:value IN (SELECT key_column FROM single_table WHERE some_expr)
    9. range:只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。在该类型中ref列为NULL。当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range
    10. index:该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。
    11. all:对于每个来自于先前的表的行组合,进行完整的表扫描。如果表是第一个没标记const的表,这通常不好,并且通常在它情况下很差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常数值或列值被检索出。

    possible_keys:possible_keys列指出MySQL能使用哪个索引在该表中找到行。注意,该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。

    key:key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

    key_len:key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。注意通过key_len值我们可以确定MySQL将实际使用一个多部关键字的几个部分。

    ref:ref列显示使用哪个列或常数与key一起从表中选择行。

    rows:rows列显示MySQL认为它执行查询时必须检查的行数。

    Extra:该列包含MySQL解决查询的详细信息。

    1. Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
    2. Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。
    3. range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。对前面的表的每个行组合,MySQL检查是否可以使用range或index_merge访问方法来索取行。
    4. Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行。通过根据联接类型浏览所有行并为所有匹配WHERE子句的行保存排序关键字和行的指针来完成排序。然后关键字被排序,并按排序顺序检索行。
    5. Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。当查询只使用作为单一索引一部分的列时,可以使用该策略。
    6. Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。典型情况如查询包含可以按不同情况列出列的GROUP BY和ORDER BY子句时。
    7. Using where:WHERE子句用于限制哪一个行匹配下一个表或发送到客户。除非你专门从表中索取或检查所有行,如果Extra值不为Using where并且表联接类型为ALL或index,查询可能会有一些错误。
    8. Using sort_union(...), Using union(...), Using intersect(...):这些函数说明如何为index_merge联接类型合并索引扫描。
    9. Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。并且,按最有效的方式使用索引,以便对于每个组,只读取少量索引条目。

    单列索引的使用

    准备工作

    给id加主键索引:

    再分别给name、city、country、address加上普通索引:

    注:以上五个索引都是单列索引。

    使用情况

    只涉及到其中的一个字段时,都能使用到索引(以e_name为例):

     

    注:模糊查询时,%如果在前面,那么不会使用索引。

    涉及到多个索引字段时,如果这些索引字段中,存在主键索引,那么只会使用该索引(即:MYSQL优化器会选出并先执行最“严”的索引):

    提示:possible_key中,只是SQL语句里涉及到的索引;key中才是实际上执行查询操作时使用到了的索引。

    涉及到多个索引字段时,如果这些索引字段中,不存在主键索引的话,那么就会使用该使用的索引(注:如果通过其中的部分索引就能准确定位的话,那么其余的索引就不再被使用):

     

    注:多个索引时,先使用哪个索引后使用哪个索引,是由MySQL的优化器经过一些列计算后作出的抉择

    当对索引字段进行 >, <>= <=not inbetween …… and ……函数(索引字段)like模糊查询%在字段前时不会使用该索引

    注:这里对e_age字段进行了 “<” ,所以实际查询时,并没有使用e_age的索引。

    提示:在实际使用时,如果涉及到多列,我们一般都不会将这些列一 一创建为单列索引,而是将这些列创建为组合索引


    组合索引的使用

    最左原则

           假设组合索引为:a,b,c的话;那么当SQL中对应有:aa,ba,b,c的时候,可称为完全满足最左原则;当SQL中查询条件对应只有a,c的时候,可称为部分满足最左原则;当SQL中没有a的时候,可称为不满足最左原则

    注:MySQL5.7开始,会自动优化,如:会把c,b,a优化为a,b,c使之完全遵循最左原则;会把c,a优化为a,c使之部
           分遵循最左原则
    。即:SQL语句中的对应条件的先后顺序无关。

    准备工作

    创建了组合索引:e_name,e_age,e_country,e_city

    使用情况

    完全满足最左原则

    注:与条件的先后无关(这是因为MYSQL5.7开始,对索引全排列有优化,会自动优化为按组合索引的顺序进行查询)
           即:下面这样的话,也是会完整的走组合索引的:

    部分满足最左原则

    注:此SQL中,只有e_name和e_country满足部分最左原则(e_name满足),所以到e_name字段时会走组合所以,但是
           只会走到e_name那里,到e_country时就不会使用组合索引了。

    不满足最左原则

    满足(部分满足)最左原则的字段里,有字段不满足“索引”自身的使用规范

    说明:如果SQL语句里的字段里,满足了最左原则,但是不满足“索引”自身的使用规范,那么组合索引走到这里之后,
               不会再往下走了。

    如图所示:由于e_age字段使用了“>”符号,不符合“索引”自身的使用规范,那么当“e_name”走完组合索引后,
                      走到“e_age”时,该字段及其后面的字段不会再走组合索引了。


    【补充】使用组合索引时,不遵循最左原则仍然会走索引的特殊种情况

    相关概念

    聚集索引与非聚集索引

           每个InnoDB表具有一个特殊的索引称为聚簇索引(也叫聚集索引,聚类索引,簇集索引)。如果表上定义有主键,该主键索引就是聚簇索引。如果未定义主键,MySQL取第一个唯一索引(unique)而且只含非空列(NOT NULL)作为主键,InnoDB使用它作为聚簇索引。如果没有这样的列,InnoDB就自己产生一个这样的ID值,它有六个字节,而且是隐藏的,使其作为聚簇索引。

           表中的聚簇索引(clustered index )就是一级索引,除此之外,表上的其他非聚簇索引都是二级索引,又叫辅助索引(secondary indexes)。

    回表

            当二级索引无法直接查询到(SQL中select需要的所有)列的数据时,会通过二级索引查询到聚簇索引(即:一级索引)后,再根据(聚集索引)查询到(二级索引中无法提供)的数据,这种通过二级索引查询出一级索引,再通过一级索引查询(二级索引中无法提供的)数据的过程,就叫做回表。

    当无需回表时,不遵循最左原则也是会走组合索引

    如,现有表:

    id是主键,其余三个字段组成联合索引:

    当不需要进行回表时,即便我们的SQL不满足组合索引最左原则,也会走组合索引的,如:

            这里where后直接是gender时, 是不遵循组合索引的最左原则的,但是查询计划显示使用了索引的。这是因为: 对这张表进行select *,相当于进行select id,name,age,gender,其中,id是主键(一级索引),name、age、gender是组合索引(二级索引),这里查询时,能直接从索引中拿到想要查询的所有列的数据,是不需要回表查询的,所以这里哪怕sql写法上不遵循最左原则,但是仍然是会走索引的。

    如果这个时候,我们加一个普通的motto字段:

     

    使用相同的SQL进行查询,可看到:

     

            此时进行select *,相当于进行select id,name,age,gender,motto,其中motto字段是从索引(一级索引、二级索引)里面获取不到数据的,是肯定需要回表的。而查询条件又不遵循最左原则,所以不会走组合索引。

    注:其它情况下,只有(完全或部分)遵循了最左原则,才会走组合索引


    ^_^ 如有不当之处,欢迎指正

    ^_^ 参考链接
                  https://www.cnblogs.com/DreamDrive/p/7752960.html
                  https://www.cnblogs.com/tommy-huang/p/4317305.html
                  https://blog.csdn.net/linjpg/article/details/56054994
                  https://www.jb51.net/article/118371.html

                  https://www.csdn.net/gather_2a/MtTaMgwsNzY0OS1ibG9n.html

    ^_^ 如涉及侵权问题,请及时联系我

    ^_^ 本文已经被收录进《程序员成长笔记(二)》,笔者JustryDeng

    展开全文
  • 使用VBA动态创建SQL查询语句

    千次阅读 2018-02-28 07:19:00
    在VBA使用ADO可以高效的查询数据,但是写SQL查询语句是个有些令人头痛的事情,其实在ADO中用到的SQL语句的语法并不是很复杂,很多时候是由于即要思考SQL的语法,又要用VBA的字符串连接命令,最终搞得一团糟。...

            在VBA使用ADO可以高效的查询数据,但是写SQL查询语句是个有些令人头痛的事情,其实在ADO中用到的SQL语句的语法并不是很复杂,很多时候是由于即要思考SQL的语法,又要用VBA的字符串连接命令,最终搞得一团糟。

            其实,这个创建SQL语句的工作可以交给VBA来完成,当然其前提是——你已经想清楚了要如何构建你的SQL。

            1. 定义参数

            为了和VBA中数组元素编号一致,称为“参数0”到“参数4”,共5个,分别对应SQL语句的不同部分。代码中给出了“聚合SQL”和“非聚合带排序”两个例子。

            2. 使用变量

            参数数组也可以用变量,比如需要查询当前年份的记录,参数3初始赋值为"[年]='?'",然后使用下面代码进行替换

    aPara(2) = VBA.Replace(aPara(2), REPLACE_CHAR, Year(Date))
            3. SQL语句模板

            将SQL模板定义为"SELECT ? FROM ? WHERE ? ? ?",共有5个问号,对应5个参数。

            4. 可选SQL关键字

            由于GROUP BY和ORDER BY是可选部分,因此如果不需要相关部分的话,请将相应的参数置空,参见“非聚合带排序”。

            5. 动态创建SQL字符串

            准备工作已经完成,循环替换就可以创建SQL字符串,Replace方法的第5个参数需要指定为1,以实现逐个替换。

    sSQL = VBA.Replace(sSQL, REPLACE_CHAR, aPara(i), 1, 1, vbTextCompare)
            6. 完整代码
    Sub CreateSQL()
        Dim sSQL, aPara
        Const REPLACE_CHAR = "?"
    '==============================================================
    '    aPara = Array("Fields", _  参数0: 字段
    '                "Table", _     参数1:  数据表
    '                "Where", _     参数2:  条件
    '                "Group By", _  参数3: 分组
    '                "Order By")    参数4: 排序
    '--------------------------------------------------------------
    ' 聚合SQL
    '    aPara = Array("[班级],[科目],SUM([成绩])", _
    '                  "[成绩表$A:K]", _
    '                  "[年]='2017'", _
    '                  "[班级]", _
    '                  "[班级],[科目]")
    '--------------------------------------------------------------
    ' 非聚合带排序
        aPara = Array("[班级],[科目],[姓名],[成绩]", _
                      "[成绩表$A:K]", _
                      "[年]='2017'", _
                      "", _
                      "[班级],[科目]")
    '--------------------------------------------------------------
    ' 使用变量替换参数
        aPara(2) = VBA.Replace(aPara(2), REPLACE_CHAR, Year(Date))
    '==============================================================
        sSQL = "SELECT ? FROM ? WHERE ? ? ?"
        For i = 0 To 4
            If i > 2 And Len(aPara(i)) > 0 Then
                aPara(i) = IIf(i = 3, "GROUP BY ", "ORDER BY ") & aPara(i)
            End If
            sSQL = VBA.Replace(sSQL, REPLACE_CHAR, aPara(i), 1, 1, vbTextCompare)
            'Debug.Print sSQL
        Next
        Debug.Print sSQL
    End Sub
    
    
            7. SQL查询字符串 
    ' 聚合SQL
    SELECT [班级],[科目],SUM([成绩]) FROM [成绩表$A:K] WHERE [年]='2017' GROUP BY [班级] ORDER BY [班级],[科目]
    
    ' 非聚合带排序
    SELECT [班级],[科目],[姓名],[成绩] FROM [成绩表$A:K] WHERE [年]='2018'  ORDER BY [班级],[科目]

           每次只需要稍加修改参数数组就可以创建出SQL语句,感觉不错吧!大家也可以把这个Sub过程改造成Function函数,更便于在代码中调用。




    展开全文
  • 当数据库中数据量很大时,查找数据会变得很慢,我们就可以通过索引来提高数据库的查询效率。 索引的使用 查看表中已有索引: show index from 表名; 说明: 主键列会自动创建索引 索引的创建: -- ....
  • 查询视图的sql语句(mysql创建视图sql语句)2020-07-24 12:07:14共10个回答两种方式,一种是直接在sqlserver的列表中找到,另一种用写语句的方式查询.方法一:1、登陆sqlservermanagerstudio.2、在左边的树找到自己要查询...
  • 使用CREATE 语句创建索引 CREATE INDEX index_name ON table_name(column_name,column_name) include(score) ---普通索引 CREATE UNIQUE INDEX index_name ON table_name (column_name) ;---非空索引 CREATE ...
  • 数据库索引创建,查询

    千次阅读 2018-04-26 10:55:14
    索引的详解索引的创建 主键索引的创建 主键索引的创建有两种方式, 1 在创建表的时候, 直接在指定列或者某几列为主键 create table aaa(id int primary key , name varchar(32)) 2添加表后, 对指定列创建索引...
  • 什么情况下执行相同的sql查询语句会使用同一个Sqlsession?设么情况下相同的sql查询语句会创建不同的Sqlsession从而导致一级缓存失效?(不好意思默认是5C,发布时候没注意,有会的我可以加微信发红包)
  • mysql多表查询创建视图

    万次阅读 2018-06-26 20:12:48
    1.union联合查询 将多个select语句的结果纵向组合 select * from stuinfo union select * from stuinfoo; union: 1.all #显示全部记录 2.distinct #(去除重复的值 他是默认) select * from stuinfo union all...
  • 索引创建使用

    千次阅读 2020-01-10 14:41:20
    索引的作用 数据库中现在有一百万条记录,...如果在Id列上创建索引,SQL Server不需要任何扫描,直接在索引里面找645853,就可以得知这一行的位置。可见,索引的建立可以加快数据库的查询速度。 索引的分类 不...
  • 一、可以创建多个索引嘛? 可以创建多个索引的。 需要开发人员根据实际的用途以及数据库中记录的情况,来进行判断。 通常来说,表的索引越多,其查询的速度也就越快。但是,表的insert/update速度则会降低。这主要是...
  • 用一条sql查出mysql中数据库的创建时间(create_time)...........
  • mysql视图之创建视图(CREATE VIEW)和使用限制

    万次阅读 多人点赞 2018-07-12 15:26:10
    mysql以两种方式处理对视图的查询:第一种方式,MySQL会根据视图定义语句创建一个临时表,并在此临时表上执行传入查询。第二种方式,MySQL将传入查询查询定义为一个查询并执行组合查询。mysql支持版本系统的视图...
  • 创建使用视图

    千次阅读 2017-12-05 14:56:14
    /* 2017-04-27 周四晚上机实践实验五 创建视图,并查询创建后的视图,测试该视图...--(1)设计一个视图,用于简化用户的查询操作,例如:把上面的三个表做自然连接,使用外连接,可以保留学生表和课程表的所有记录。
  • 动态创建Lambda表达式实现高级查询

    万次阅读 热门讨论 2016-05-14 09:43:32
    中有一个功能是一个高级查询的需求,在查询条件方面大概有7、8个查询条件。需求就是如果一个条件都不输入就默 认查询全部的数据,那个条件不为空的时候就在查询条件上面添加对响应字段的限制,也就是说我们在写...
  • 触发器创建使用

    万次阅读 2018-05-14 13:43:12
    它与存储过程的区别在于触发器是被动调用的 ,即在满足特定事件的情况下被执行,而存储过程是在使用操作语句时主动进行调用。触发器大致分为两种:DDL触发器和DML触发器,相对应的具体定义如下。2.创建触发器2.1创建...
  • mysql索引的创建使用

    千次阅读 2017-03-18 23:42:05
    索引:其实是根据我们的数据库结构抽取的另外一个映射我们数据类型的数据结构,一般实现了B-Tree或B+查询算法来快速定位到我们数据库的信息的结构,速度快,但并不是所有的查询都用索引,这个需要根据实际场景业务...
  • 几乎所有的小伙伴都可以随口说几句关于创建索引的优缺点,也知道什么时候创建索引能够提高我们的查询性能,什么时候索引会更新,但是你有没有注意到,即使你设置了索引,有些时候索引他是不会生效的!这不仅考察了...
  • mysql创建视图包含子查询的解决方法

    万次阅读 2017-02-07 15:16:30
    mysql 创建视图出现1349 View's SELECT contains a subquery in the FROM clause解决办法 习惯用oracle创建视图,...查询:CREATE or replace VIEW view_order_summary AS select a.opuser,a.audit_status,a.tota
  • SQL Server的数据库创建、修改、查询、删除

    万次阅读 多人点赞 2018-08-14 10:08:40
    一、创建数据库(create database 数据库名) 基本常识: 语法: 建立数据库: 二、修改数据库 修改数据库名字 向数据库中添加文件组和文件 修改数据库文件 三、查询数据库sp_helpdb、sp_spaceued sp_helpdb:...
  • postgresql创建序列查询序列

    千次阅读 2019-01-02 16:38:48
    ## 序列号(SERIAL)类型 smallserial(int2), serial(int4) bigserial(int8) DROP TABLE t_student; CREATE TABLE t_student ( "Id" serial, ...OWNED BY : 可以直接指定一个表的字段,也可以不指定。
  • oracle中创建视图并查询视图

    万次阅读 2016-08-23 21:48:30
    1.创建视图:    CREATE OR REPLACE VIEW TB_CONF AS SELECT SI.SYSID id,SI.SYS_NAME_EN AS sysName,SI.SYS_NAME_CN AS sysCname,SI.RECEIVE_STATUS AS sysReceiveStatus,   SI.SEND_STATUS AS sysSendStatus,SI...
  • MySQL索引创建使用

    万次阅读 多人点赞 2019-03-12 17:56:59
    背景 最近在深化学习数据库相关知识,借此机会总结记录一番,本来想自己总结概括一下,但是看到一...关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL...
  • 数据库中存在多种对象,表和视图都是数据库中的对象,创建视图时名称不能和表明重名,视图实际上是代表了一段sql查询语句,可以理解成视图是一张虚拟的表,表中的数据会随着原表的改变而改变。 为什么使用视图? ...
  • 这时候我们可以通过建立DBLink建立视图,实现跨数据库的数据访问。  以下实例,我们进行数据库A访问数据库B中T_S1表数据。前提数据库用户需要有connect,resource,dba权限。 简单步骤如下: 1、在数据库A中建立...
  • SQL Server中数据表的创建查询、修改、删除

    万次阅读 多人点赞 2018-08-15 10:12:50
    1.数据表的创建(create table 表名) 2.数据表的查询 3.数据表的修改(修改数据表的名字) 4.数据表的删除(drop table 表名)   0.码仙励志 每一个成功的人,都有一段沉默的努力时光,里面有艰辛的汗水,也...
  • 使用SQL语句创建数据库

    万次阅读 多人点赞 2019-06-18 08:23:13
    使用SQL语句创建数据库 开发工具与关键技术:SQL Server 2014 、SQL 作者:易金亮 撰写时间:2019.06.17 数据库可以用多种方式来创建,在还没学习SQL语句的时候,我是通过在数据库选择数据库然后右键新建数据库来...
  • sql语句的创建关联表和简单的跨表查询

    千次阅读 多人点赞 2019-03-28 20:22:21
    sql语句的创建关联表和简单的跨表查询简单介绍表的创建==创建数据库====创建一个用户并授权====指定使用某个数据库====老师表、班级表、学生表====给老师表创建一个唯一索引====添加外键,使表关联====往表内插入...
  • dblink的创建使用总结

    万次阅读 2019-05-16 23:58:12
    创建database link的时候,oracle在数据字典中存储了相关的database link的信息,在使用database link的时候,oracle再通过oracle net用户预先定义好的连接信息访问相应的远程数据库来完成相应的工作。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,763,132
精华内容 705,252
关键字:

创建查询可以使用什么