本文分为两个部分,第一部分是谈聚簇索引和非聚簇索引,第二部分谈sql中exists和in的用法
第一部分
首先这两个都是索引,索引一般用在表中某些需要频繁读取的字段上,这是考虑到对表的写操作时要同时更新这些索引,有性能损耗。
聚簇索引:如果有n条数据,就有n个索引项,以B+树方式存在磁盘上。叶子节点存放的是所有实际的数据,这些数据同时是物理连续的。可以在logn的时间内找到结果,同时也可以按序遍历(不使用索引)。但在插入删除时,如果填充因子设置的太大(100%)时,可能会进行大量数据的磁盘移动。
非聚簇索引:和聚簇类似,不过叶节点存放的是所有实际数据的id和它的指针。因此它的缺点是当访问数据时,要比聚簇索引方式多查找一次(多一次通过指针查找到数据的实际位置)。但是由于是指针,所以它的实际数据可以分散的存储到硬盘的各个位置,同时更新操作时只要移动id和相应的指针就行了,不用移动实际数据。
参考:
第二部分
首先说in和exists的用法
in:可以使用where id in(……)的方式,后面接的是一个查询结果,类似一个集合,例如select id…或者(1,2,3),返回的也是一个集合。
exists:可以使用where exists(……)或者and exists(……)的方式,只要括号里返回结果不为空,exists就返回true,否则为false。
这两个都是子查询,不过对于in,是先执行in子句,然后再和主查询链接,得到查询结果。
对于exists,先执行主查询,然后对每条查询记录,在exists中判断是否为true,如果是true则保留这条记录,否则舍弃这条数据,最后返回整个查询结果。
总结:对于主查询里的为表A,子查询里的表为B。当子查询表B小时,用in比较好,因为先执行B可以减少比较次数(这里可能不是很对,但大概就是这意思)。当主查询表A小时,用exists比较好。
参考: