❶ sql查询一个表里的数据在另一个表是否存在
--创建测试表
CREATE TABLE AA_TMP(ID VARCHAR2(10)); --插入目标表
CREATE TABLE AA_LOOKUP(ID VARCHAR2(10));--要插入的数据
INSERT INTO AA_LOOKUP VALUES('1');
INSERT INTO AA_LOOKUP VALUES('2');
INSERT INTO AA_LOOKUP VALUES('3');
COMMIT;
--插入数据不存在时更新
INSERT INTO AA_TMP(ID)
SELECT ID FROM AA_LOOKUP A
WHERE NOT EXISTS
(SELECT 1 FROM AA_TMP B
WHERE A.ID=B.ID
)
;
COMMIT;
❷ 连接池已经配置成功但是编译时提示lookup<javax.sql.DataSource>错误怎么解决
java:comp/env
这个只是根目录.
正确的配置是tomcat下面的\conf\context.xml
<Resource name="jdbc/aaa" />
配置这样的话就把java:comp/env改成java:comp/env/jdbc/aaa
项目下web.xml中配置
<resource-ref>
<res-ref-name>jdbc/aaa<res-ref-name>
</resource-ref>
❸ sql server执行计划 怎么看消耗资源
扫描:逐行遍历数据。
先建立一张表,并给大家看看大概是什么样子的。
CREATE TABLE Person(
Id int IDENTITY(1,1) NOT NULL,
Name nvarchar(50) NULL,
Age int NULL,
Height int NULL,
Area nvarchar(50) NULL,
MarryHistory nvarchar(10) NULL,
EcationalBackground nvarchar(10) NULL,
Address nvarchar(50) NULL,
InSiteId int NULL
) ON [PRIMARY]
表中的数据14万左右,大概类似下面这样:
此表,暂时没有任何索引。
一、数据访问操作
1、表扫描
表扫描:发生于堆表,并且没有可用的索引可用时,会发生表扫描,表示整个表扫描一次。
现在,我们来对此表执行一条简单的查询语句:
SELECT * From Person WHERE Name = '公子'
查看执行计划如下:
表扫描,顾名思义就是整张表扫描,找到你所需要的数据了。
2、聚集索引扫描
聚集索引扫描:发生于聚集表,也相当于全表扫描操作,但在针对聚集列的条件如(WHERE Id > 10)等操作时,效率会较好。
下面我们在Id列来对此表加上一个聚集索引
CREATE CLUSTERED INDEX IX_Id ON Person(Id)
再次执行同样的查询语句:
SELECT * From Person WHERE Name = '公子'
执行计划如下:
为什么建的聚集索引在Id列,会对扫描有影响呢?更何况与Name条件也没关系啊?
其实,你加了聚集索引之后,表就由堆表变成了聚集表。我们知道聚集表的数据存在于聚集索引的叶级节点。因此,聚集扫描与表扫描其实差别不大,要说差别大,也得看where条件里是什么,以后返回的数据。就本条SQL语句而言,效率差别并不大。
可以看看I/O统计信息:
表扫描:
聚集索引扫描:
此处超出本文范畴了,效率不在本文考虑范围内,本文只考虑的是,各种扫描的区别,以及为何会产生。
3、聚集索引查找
聚集索引查找:扫描聚集索引中特定范围的行。
看执行以下SQL语句:
SELECT * FROM Person WHERE Id = '73164'
执行计划如下:
4、索引扫描
索引扫描:整体扫描非聚集索引。
下面我们来添加一个聚集索引,并执行一条查询语句:
CREATE NONCLUSTERED INDEX IX_Name ON Person(Name) --创建非聚集索引
SELECT Name FROM Person
查看执行计划如下:
为什么此处会选择索引扫描(非聚集索引)呢?
因为此非聚集索引能够覆盖所需要的数据。如果非聚集索引不能覆盖呢?例如,我们将SELECT改为SELECT *再来看看。
好明显,返回结果所包括的记录太多,用非聚集索引反而不合算。因此使用了聚集索引。
如果此时我们删除聚集索引,再执行SELECT *看看。
DROP INDEX Person.IX_Id
而此时没有聚集索引,所以只有使用表扫描。
5、书签查找
前面关于索引的学习我们已经知道,当在非聚集索引中并非覆盖和包含所需全部的列时,SQL Server会选择,直接进行聚集索引扫描获得数据,还是先去非聚集索引找到聚集索引键,然后利用聚集索引找到数据。
下面来看一个书签查找的示例:
SELECT * FROM Person WHERE Name = '胖胖'--Name列有非聚集索引
执行计划如下:
上面的过程可以理解为:首先通过非聚集索引找到所求的行,但这个索引并不包含所有的列,因此还要额外去基本表中找到这些列,因此要进行键查找,如果基本表是以堆进行组织的,那么这个键查找(Key Lookup)就会变成RID查找(RID Lookup),键查找和RID查找统称为书签查找。不过有时当非聚集索引返回的行数过多时,SQL Server可能会选择直接进行聚集索引扫描了。
二、流聚合操作
1、流聚合
流聚合:在相应排序的流中,计算多组行的汇总值。
所有的聚合函数(如COUNT(),MAX())都会有流聚合的出现,但是其不会消耗IO,只有消耗CPU。
例如执行以下语句:
SELECT MAX(Age) FROM Person
查看执行计划如下:
2、计算标量
计算标量:根据行中的现有值计算新值。比如COUNT()函数,多一行,行数就加1咯。
除MIN和MAX函数之外的聚合函数都要求流聚合操作后面跟一个计算标量。
SELECT COUNT(*) FROM Person
查看执行计划如下:
3、散列聚合(哈希匹配)
对于加了Group by的子句,因为需要数据按照group by 后面的列有序,就需要Sort来保证排序。注意,Sort操作是占用内存的操作,当内存不足时还会去占用tempdb。SQL Server总是会在Sort操作和散列匹配中选择成本最低的。
SELECT Height,COUNT(Id) FROM Person --查出各身高的认输
GROUP BY Height
执行计划如下:
对于数据量比较大时,SQL Server选择的是哈希匹配。
在内存中建立好散列表后,会按照group by后面的值作为键,然后依次处理集合中的每条数据,当键在散列表中不存在时,向散列表添加条目,当键已经在散列表中存在时,按照规则(规则是聚合函数,比如Sum,avg什么的)计算散列表中的值(Value)。
4、排序
当数据量比价少时,例如执行以下语句,新建一个只有数十条记录的与Person一样的表。
SELECT * INTO Person2 FROM Person2
WHERE Id < 100
再来执行同样的查询语句:
SELECT Height,COUNT(Id) FROM Person2 --只是表换成了数据量比较少的表
GROUP BY Height
执行计划如下:
三、连接
当多表连接时(包括书签查找,索引之间的连接),SQL Server会采用三类不同的连接方式:循环嵌套连接,合并连接,散列连接。这几种连接格式有适合自己的场景,不存在哪个更好的说法。
新建两张表如下
这是一个简单的新闻,栏目结构。
1、嵌套循环
先来看一个简单的Inner Join查询语句
SELECT * FROM Nx_Column AS C
INNER JOIN Nx_Article AS A
ON A.ColumnId = C.ColumnId
执行计划如下:
循环嵌套连接的图标同样十分形象,处在上面的外部输入(Outer input),这里也就是聚集索引扫描。和处在下面的内部输入(Inner Input),这里也就是聚集索引查找。外部输入仅仅执行一次,根据外部输入满足Join条件的每一行,对内部输入进行查找。这里由于是7行,对于内部输入执行7次。
根据嵌套循环的原理不难看出,由于外部输入是扫描,内部输入是查找,当两个Join的表外部输入结果集比较小,而内部输入所查找的表非常大时,查询优化器更倾向于选择循环嵌套方式。
2、合并连接
不同于循环嵌套的是,合并连接是从每个表仅仅执行一次访问。从这个原理来看,合并连接要比循环嵌套要快了不少。
从合并连接的原理不难想象,首先合并连接需要双方有序.并且要求Join的条件为等于号。因为两个输入条件已经有序,所以从每一个输入集合中取一行进行比较,相等的返回,不相等的舍弃,从这里也不难看出Merge join为什么只允许Join后面是等于号。从图11的图标中我们可以看出这个原理。
SELECT * FROM Nx_Column AS C
INNER JOIN Nx_Article AS A
ON A.ColumnId = C.ColumnId
OPTION(MERGE join)
执行计划如下:
如果输入数据的双方无序,则查询分析器不会选择合并连接,我们也可以通过索引提示强制使用合并连接,为了达到这一目的,执行计划必须加上一个排序步骤来实现有序。这也是上述SQL语句为什么要加OPTION(MERGE join)的原因。上述对Article表的ColumnId列进行了排序。
3、哈希连接
散列连接同样仅仅只需要只访问1次双方的数据。散列连接通过在内存中建立散列表实现。这比较消耗内存,如果内存不足还会占用tempdb。但并不像合并连接那样需要双方有序。
要进行下面这两个实现,得把两个列的聚集索引不要建在ColumnId列,否则不会采用哈希连接。
ALTER TABLE PK_Nx_Column DROP CONSTRAINT PK_Nx_Column --删除主键
DROP INDEX Nx_Column.PK_Nx_Column --删除聚集索引
CREATE CLUSTERED INDEX IX_ColumnName ON Nx_Column(ColumnName) --创建聚集索引
--这里再设置回主键就可以了,有了聚集索引,就不能随主键默认建啦
还要删除另外一个表Article的聚集索引哦。
然后执行以下查询:
SELECT * FROM Nx_Column AS C
INNER JOIN Nx_Article AS A
ON A.ColumnId = C.ColumnId
执行计划如下:
要删除掉聚集索引,否则两个有序输入SQL Server会选择代价更低的合并连接。SQL Server利用两个上面的输入生成哈希表,下面的输入来探测,可以在属性窗口看到这些信息,如图15所示。
❹ 怎么使用look up控件将源表中的
LOOKUP 控件的主要目的是:
从关系型的表、视图或者同义词中根据lookup 条件查询lookup port,返回查询结果,供mapping 中的其他控件使用或者插入到目标表
LOOKUP 控件能够完成的任务包括:
得到一个关联的值,例如根据USER_ID 得到USER_NAME
执行一个计算,例如得到计算公式中的一个乘数
更新缓慢变化的维表,可以用LOOKUP 来判断当前记录是否在目标表中已经存在
LOOKUP 控件的类型:
Connected:直接从其他控件获得输入信息;可以使用静态或者动态的Cache;只缓冲mapping 中用到的port;每条记录可以返回多个column,并且能够插入到动态Cache 中;查询条件无匹配时,返回所有输出port 的默认值,如果使用动态Cache,Informatica Server把记录毫无改变的保留在Cache 中;支持用户定义的默认值;返回多个输出值到另一个控件中
Unconnected:间接的从其他控件的:LKP 表达式的结果来获得输入信息;只能使用静态Cache;缓冲所有的port;每条记录只能返回一列;查询条件无匹配时,返回NULL;不支持用户定义的默认值;将返回值输出到定义:LKP 表达式的控件中
Connected LOOKUP 控件的处理过程
1.直接从mapping 中的另一个控件获得输出数据
2.对于每一条数据,Informatica Server 根据LOOKUP 控件中的条件去查询LOOKUP表或者是Cache
3.如果LOOKUP 控件是Uncached 或者使用的是静态的Cache,Informatica Server返回查询的结果;如果使用的是动态的Cache,Informatica Server 在Cache 中查询从LOOKUP表中查询得到的结果,如果在Cache 中不存在,则将结果插入到Cache 中,如果在Cache中存在,则更新这些记录或者不做改变,同时标记这些记录是“插入”、“更新”、“无变化”等类型
4.然后将结果返回到下一个控件
可以将上面的经过经过filter 或者router 控件来得到对于目标表中不存在的记录
Unconnected LOOKUP 控件的处理过程
1.相关控件想间接的从其他LOOKUP 控件的:LKP 表达式的结果来获得输入信息,例如UPDATE STRATEGY 控件
2.对于每一条数据,Informatica Server 根据LOOKUP 控件中的条件去查询LOOKUP表或者是Cache
3.Informatica Server 返回一个值到LOOKUP 控件的return port
4.Informatica Server 返回值到调用:LKP 的控件的表达式中
Unconnected LOOKUP 控件的主要用处是更新缓慢变化的维
LOOKUP 控件的组件
LOOKUP 表
需要有源或者是目标中的一个可以访问这个LOOKUP 表;可以是一个单独的表,也可以使用SQL 语句覆盖来得到一个包括多个表的查询通过连接到数据来引入LOOKUP 表的定义,可以通过数据库的本地驱动或者是ODBC 来进行连接,但是使用数据库本身的本地驱动性能更好一些对于非常大的LOOKUP 表,考虑添加索引来提高查询的性能,索引需要包括LOOKUP 条件中的所有的字段对于Cache LOOKUP,将LOOKUP 的ORDER BY 子句中的包含在索引中即
可;对于Uncached LOOKUP,要把LOOKUP 条件里面的自动都加入到索引中
LOOKUP 端口
I:输入端口
O:输出端口
L:查询端口,在默认的SQL 中出现,LOOKUP 表中的每列都被自动的定义
为L 和O 端口,可删除
R:无连接LOOKUP 中的返回端口
LOOKUP 属性
Lookup SQL Override 只能在cache enable 的情况下才能用,另外不要输入ORDER BY 子句,即使输入INFORMATICA 也会产生ORDER BY 子句
Lookup Caching Enabled:如果选中,查询一次表,以后的记录都从缓冲中去查询;如果不选,每条记录都从数据库中查询一次
Lookup Policy on Multiple Match:确定在uncached 和static cache 的情况下如何处理查询得到的多条记录,可以取得第一条、最后一条或者是报错;在dynamic cached 的情况下,如果查询得到多条记录,会报错
Dynamic Lookup Cache:当把经过的记录插入到目标表的同时,插入或者更新cache里面的记录
Insert Else Update:如果选中整个选项并且进入LOOKUP 控件的记录类型是INSERT,那么对于不存在的记录进行插入,对于存在的记录进行更新;如果不选中这个选项,只是对那些是INSERT 类型的记录在cache 进行寻找,找不到则插入,否则不做其他操作
Update Else Insert:如果选中整个选项并且进入LOOKUP 控件的记录类型是UPDATE,那么对于存在的记录进行更新,对于不存在的记录进行插入;如果不选中这个选项,只是对那些是UPDATE 类型的记录在cache 进行寻找,找到则更新,否则不做其他操作。
LOOKUP 查询
默认产生ORDER BY 子句,并且顺序与SELECT 中的字段的顺序是一致的SYBASE 中的ORDER BY 子句最多可以有16 个字段,因此如果LOOKUP 中有超过16 个字段的查询,必须使用多个LOOKUP 控件进行查询当在OVERRIDE SQL 中要写WHERE 子句时,如果是dynamic,必须在LOOKUP控件前面添加一个FILTER 控件,来确保只有满足条件的记录被插入到cache 和目标表中如果没有cache,sql override 无效;在override 中SELECT 的字段必须与L 端口和O 端口一致
LOOKUP 条件
类似于WHERE 子句;条件中的数据类型必须一致;多个条件之间的关系是“与(AND)”;NULL 值是可以匹配的;
如果有多个条件,把带等号的条件放在前面,可以提高性能;对于有多个匹配的情况,可以选择返回的类型:第一个匹配、最后一个匹配、返回错误;INFORMATICA 的ORDER BY 是升序排列的dynamica cache 的情况下,因为不能返回多个记录,所以只能使用等号的条件
LOOKUP tips
给LOOKUP 条件中的字段添加索引把带有等号的条件放置在前面把较小的LOOKUP 表进行cache在数据库中进行表的关联:如果LOOKUP 表和源表在同一个数据里面,而且cache是不可能的,就在数据库里面进行表关联对于静态的LOOKUP 表,尽量使用永久性的cache:这样可以在多个session 见复用如果想在EXPRESSION 中使用:LKP 来调用查询的结果,引入一个unconnected 的LOOKUP
对于cache 的LOOKUP,重定义ORDER BY 子句:1)generate SQL;2)按照LOOKUP
条件中的字段的顺序添加ORDER BY 语句;3)在ORDER BY 语句后面添加--,作为重定
义的记号,否则出错
❺ sql server里面 include什么意思
如果返回的数据列就包含于索引的键值中,或者包含于索引的键值+聚集索引的键值中,那么就不会发生Bookup Lookup,因为找到索引项,就已经找到所需的数据了,没有必要再到数据行去找了。这种情况,叫做索引覆盖;
❻ 哪位高手能告诉我:用主/细表、TABLE的LOOKUP字段、QUERY的查找字段
用BDE没问题用ADO(ADOQUERY)的Lookup编辑有问题,可以该为计举动当作段解决!
❼ sql如何实现vlookup功能
这太简单啦
比如A表有姓名,B表也有姓名
select * from A where 姓名 in(select 姓名 from B)