2. 选择最有效率的表名顺序(只在基于规则的优化器中有效) 。
ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并. 。
例如: 表 TAB1 16,384 条记录 。
表 TAB2 1 条记录 。
选择TAB2作为基础表 (最好的方法) 。
select count(*) from tab1,tab2 执行时间0.96秒 。
选择TAB2作为基础表 (不佳的方法) 。
select count(*) from tab2,tab1 执行时间26.09秒 。
如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表. 。
例如: EMP表描述了LOCATION表和CATEGORY表的交集. 。
SELECT *
FROM LOCATION L , 。
CATEGORY C, 。
EMP E
WHERE E.EMP_NO BETWEEN 1000 AND 2000 。
AND E.CAT_NO = C.CAT_NO 。
AND E.LOCN = L.LOCN 。
将比下列SQL更有效率
SELECT *
FROM EMP E ,
LOCATION L ,
CATEGORY C 。
WHERE E.CAT_NO = C.CAT_NO 。
AND E.LOCN = L.LOCN 。
AND E.EMP_NO BETWEEN 1000 AND 2000 。
3. WHERE子句中的连接顺序. 。
ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾. 。
例如:
(低效,执行时间156.3秒) 。
SELECT …
FROM EMP E
WHERE SAL > 50000 。
AND JOB = ‘MANAGER’
AND 25 < (SELECT COUNT(*) FROM EMP 。
WHERE MGR=E.EMPNO); 。
(高效,执行时间10.6秒) 。
SELECT …
FROM EMP E
WHERE 25 < (SELECT COUNT(*) FROM EMP 。
WHERE MGR=E.EMPNO) 。
AND SAL > 50000 。
AND JOB = ‘MANAGER’; 。
4. SELECT子句中避免使用 ‘ * ‘
当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用 ‘*’ 是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,ORACLE在解析的过程中, 会将’*’ 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间. 。
5. 减少访问数据库的次数
当执行每条SQL语句时, ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等等. 由此可见, 减少访问数据库的次数 , 就能实际上减少ORACLE的工作量. 。
例如,
以下有三种方法可以检索出雇员号等于0342或0291的职员. 。
方法1 (最低效)
SELECT EMP_NAME , SALARY , GRADE 。
FROM EMP
WHERE EMP_NO = 342; 。
SELECT EMP_NAME , SALARY , GRADE 。
FROM EMP
WHERE EMP_NO = 291; 。
方法2 (次低效)
DECLARE 。
CURSOR C1 (E_NO NUMBER) IS 。
SELECT EMP_NAME,SALARY,GRADE 。
FROM EMP 。
WHERE EMP_NO = E_NO; 。
BEGIN
OPEN C1(342); 。
FETCH C1 INTO …,..,.. ; 。
OPEN C1(291); 。
FETCH C1 INTO …,..,.. ; 。
CLOSE C1; 。
END;
方法3 (高效)
SELECT A.EMP_NAME , A.SALARY , A.GRADE, 。
B.EMP_NAME , B.SALARY , B.GRADE 。
FROM EMP A,EMP B 。
WHERE A.EMP_NO = 342 。
AND B.EMP_NO = 291; 。
注意:
在SQL*Plus , SQL*Forms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量 ,建议值为200. 。
6. 使用DECODE函数来减少处理时间 。
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表. 。
例如:
SELECT COUNT(*),SUM(SAL) 。
FROM EMP
WHERE DEPT_NO = 0020 。
AND ENAME LIKE ‘SMITH%’; 。
SELECT COUNT(*),SUM(SAL) 。
FROM EMP
WHERE DEPT_NO = 0030 。
AND ENAME LIKE ‘SMITH%’; 。
你可以用DECODE函数高效地得到相同结果 。
SELECT COUNT(DECODE(DEPT_NO,0020,’X’,NULL)) D0020_COUNT, 。
COUNT(DECODE(DEPT_NO,0030,’X’,NULL)) D0030_COUNT, 。
SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL, 。
SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SAL 。
FROM EMP WHERE ENAME LIKE ‘SMITH%’; 。
类似的,DECODE函数也可以运用于GROUP BY 和ORDER BY子句中. 。
7. 用TRUNCATE替代DELETE 。
当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况) 。
而当运用TRUNCATE时, 回滚段不再存放任何可被恢复的信息.当命令运行后,数据不能被恢复.因此很少的资源被调用,执行时间也会很短. 。
TRUNCATE只在删除全表或分区适用,TRUNCATE是DDL不是DML。
8. 用Where子句替换HAVING子句 。
避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销. 。
例如:
低效:
SELECT REGION,AVG(LOG_SIZE) 。
FROM LOCATION 。
GROUP BY REGION 。
HAVING REGION REGION != ‘SYDNEY’
AND REGION != ‘PERTH’
高效
SELECT REGION,AVG(LOG_SIZE) 。
FROM LOCATION 。
WHERE REGION REGION != ‘SYDNEY’
AND REGION != ‘PERTH’
GROUP BY REGION 。
HAVING 中的条件一般用于对一些集合函数的比较,如COUNT() 等等. 除此而外,一般的条件应该写在WHERE子句中。
9. 减少对表的查询
在含有子查询的SQL语句中,要特别注意减少对表的查询. 。
例如:
低效
SELECT TAB_NAME 。
FROM TABLES 。
WHERE TAB_NAME = ( SELECT TAB_NAME 。
FROM TAB_COLUMNS 。
WHERE VERSION = 604) 。
AND DB_VER= ( SELECT DB_VER 。
FROM TAB_COLUMNS 。
WHERE VERSION = 604) 。
高效
SELECT TAB_NAME 。
FROM TABLES 。
WHERE (TAB_NAME,DB_VER) 。
= ( SELECT TAB_NAME,DB_VER) 。
FROM TAB_COLUMNS 。
WHERE VERSION = 604) 。
Update 多个Column 例子: 。
低效:
UPDATE EMP 。
SET EMP_CAT = (SELECT MAX(CATEGORY) FROM EMP_CATEGORIES), 。
SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CATEGORIES) 。
WHERE EMP_DEPT = 0020; 。
高效:
UPDATE EMP 。
SET (EMP_CAT, SAL_RANGE) 。
= (SELECT MAX(CATEGORY) , MAX(SAL_RANGE) 。
FROM EMP_CATEGORIES) 。
WHERE EMP_DEPT = 0020; 。
10. 通过内部函数提高SQL效率. 。
SELECT H.EMPNO,E.ENAME,H.HIST_TYPE,T.TYPE_DESC,COUNT(*) 。
FROM HISTORY_TYPE T,EMP E,EMP_HISTORY H 。
WHERE H.EMPNO = E.EMPNO 。
AND H.HIST_TYPE = T.HIST_TYPE 。
GROUP BY H.EMPNO,E.ENAME,H.HIST_TYPE,T.TYPE_DESC; 。
通过调用下面的函数可以提高效率. 。
FUNCTION LOOKUP_HIST_TYPE(TYP IN NUMBER) RETURN VARCHAR2 。
AS
TDESC VARCHAR2(30); 。
CURSOR C1 IS 。
SELECT TYPE_DESC 。
FROM HISTORY_TYPE 。
WHERE HIST_TYPE = TYP; 。
BEGIN
OPEN C1;
FETCH C1 INTO TDESC; 。
CLOSE C1;
RETURN (NVL(TDESC,’?’)); 。
END;
FUNCTION LOOKUP_EMP(EMP IN NUMBER) RETURN VARCHAR2 。
AS
ENAME VARCHAR2(30); 。
CURSOR C1 IS 。
SELECT ENAME 。
FROM EMP 。
WHERE EMPNO=EMP; 。
BEGIN
OPEN C1;
FETCH C1 INTO ENAME; 。
CLOSE C1;
RETURN (NVL(ENAME,’?’)); 。
END;
SELECT H.EMPNO,LOOKUP_EMP(H.EMPNO), 。
H.HIST_TYPE,LOOKUP_HIST_TYPE(H.HIST_TYPE),COUNT(*) 。
FROM EMP_HISTORY H 。
GROUP BY H.EMPNO , H.HIST_TYPE; 。
经常在论坛中看到如 ’能不能用一个SQL写出….’ 的贴子, 殊不知复杂的SQL往往牺牲了执行效率. 能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的。
11. 使用表的别名(Alias) 。
当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误. 。
Column歧义指的是由于SQL中不同的表具有相同的Column名,当SQL语句中出现这个Column时,SQL解析器无法判断这个Column的归属。
12. 用EXISTS替代IN 。
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率. 。
低效:
SELECT *
FROM EMP (基础表) 。
WHERE EMPNO > 0 。
AND DEPTNO IN (SELECT DEPTNO 。
FROM DEPT
WHERE LOC = ‘MELB’) 。
高效:
SELECT *
FROM EMP (基础表) 。
WHERE EMPNO > 0 。
AND EXISTS (SELECT ‘X’
FROM DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO 。
AND LOC = ‘MELB’) 。
相对来说,用NOT EXISTS替换NOT IN 将更显著地提高效率,下一节中将指出。
13. 用NOT EXISTS替代NOT IN 。
在子查询中,NOT IN子句将执行一个内部的排序和合并. 无论在哪种情况下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历). 为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS. 。
例如:
SELECT …
FROM EMP
WHERE DEPT_NO NOT IN (SELECT DEPT_NO 。
FROM DEPT 。
WHERE DEPT_CAT=’A’); 。
为了提高效率.改写为:
(方法一: 高效)
SELECT ….
FROM EMP A,DEPT B 。
WHERE A.DEPT_NO = B.DEPT(+) 。
AND B.DEPT_NO IS NULL 。
AND B.DEPT_CAT(+) = ‘A’
(方法二: 最高效)
SELECT ….
FROM EMP E
WHERE NOT EXISTS (SELECT ‘X’
FROM DEPT D 。
WHERE D.DEPT_NO = E.DEPT_NO 。
AND DEPT_CAT = ‘A’); 。
14. 用表连接替换EXISTS 。
通常来说 , 采用表连接的方式比EXISTS更有效率 。
SELECT ENAME 。
FROM EMP E 。
WHERE EXISTS (SELECT ‘X’
FROM DEPT 。
WHERE DEPT_NO = E.DEPT_NO 。
AND DEPT_CAT = ‘A’); 。
(更高效)
SELECT ENAME 。
FROM DEPT D,EMP E 。
WHERE E.DEPT_NO = D.DEPT_NO 。
AND DEPT_CAT = ‘A’ ; 。
在RBO的情况下,前者的执行路径包括FILTER,后者使用NESTED LOOP。
15. 用EXISTS替换DISTINCT 。
当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXIST替换 。
例如:
低效:
SELECT DISTINCT DEPT_NO,DEPT_NAME 。
FROM DEPT D,EMP E 。
WHERE D.DEPT_NO = E.DEPT_NO 。
高效:
SELECT DEPT_NO,DEPT_NAME 。
FROM DEPT D 。
WHERE EXISTS ( SELECT ‘X’
FROM EMP E 。
WHERE E.DEPT_NO = D.DEPT_NO); 。
EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果. 。
16. 基础表的选择
基础表(Driving Table)是指被最先访问的表(通常以全表扫描的方式被访问). 根据优化器的不同, SQL语句中基础表的选择是不一样的. 。
如果你使用的是CBO (COST BASED OPTIMIZER),优化器会检查SQL语句中的每个表的物理大小,索引的状态,然后选用花费最低的执行路径. 。
如果你用RBO (RULE BASED OPTIMIZER) , 并且所有的连接条件都有索引对应, 在这种情况下, 基础表就是FROM 子句中列在最后的那个表. 。
举例:
SELECT A.NAME , B.MANAGER 。
FROM WORKER A, 。
LODGING B 。
WHERE A.LODGING = B.LODING; 。
由于LODGING表的LODING列上有一个索引, 而且WORKER表中没有相比较的索引, WORKER表将被作为查询中的基础表. 。
17. 多个平等的索引
当SQL语句的执行路径可以使用分布在多个表上的多个索引时, ORACLE会同时使用多个索引并在运行时对它们的记录进行合并, 检索出仅对全部索引有效的记录. 。
在ORACLE选择执行路径时,唯一性索引的等级高于非唯一性索引. 然而这个规则只有 。
当WHERE子句中索引列和常量比较才有效.如果索引列和其他表的索引类相比较. 这种子句在优化器中的等级是非常低的. 。
如果不同表中两个想同等级的索引将被引用, FROM子句中表的顺序将决定哪个会被率先使用. FROM子句中最后的表的索引将有最高的优先级. 。
如果相同表中两个想同等级的索引将被引用, WHERE子句中最先被引用的索引将有最高的优先级. 。
举例:
DEPTNO上有一个非唯一性索引,EMP_CAT也有一个非唯一性索引. 。
SELECT ENAME, 。
FROM EMP
WHERE DEPT_NO = 20 。
AND EMP_CAT = ‘A’; 。
这里,DEPTNO索引将被最先检索,然后同EMP_CAT索引检索出的记录进行合并. 执行路径如下: 。
TABLE ACCESS BY ROWID ON EMP 。
AND-EQUAL
INDEX RANGE SCAN ON DEPT_IDX 。
INDEX RANGE SCAN ON CAT_IDX 。
18. 等式比较和范围比较
当WHERE子句中有索引列, ORACLE不能合并它们,ORACLE将用范围比较. 。
举例:
DEPTNO上有一个非唯一性索引,EMP_CAT也有一个非唯一性索引. 。
SELECT ENAME 。
FROM EMP
WHERE DEPTNO > 20 。
AND EMP_CAT = ‘A’; 。
这里只有EMP_CAT索引被用到,然后所有的记录将逐条与DEPTNO条件进行比较. 执行路径如下: 。
TABLE ACCESS BY ROWID ON EMP 。
INDEX RANGE SCAN ON CAT_IDX 。
19. 不明确的索引等级
当ORACLE无法判断索引的等级高低差别,优化器将只使用一个索引,它就是在WHERE子句中被列在最前面的. 。
举例:
DEPTNO上有一个非唯一性索引,EMP_CAT也有一个非唯一性索引. 。
SELECT ENAME 。
FROM EMP
WHERE DEPTNO > 20 。
AND EMP_CAT > ‘A’; 。
这里, ORACLE只用到了DEPT_NO索引. 执行路径如下: 。
TABLE ACCESS BY ROWID ON EMP 。
INDEX RANGE SCAN ON DEPT_IDX 。
我们来试一下以下这种情况:
SQL> select index_name, uniqueness from user_indexes where table_name = 'EMP'; 。
INDEX_NAME UNIQUENES 。
------------------------------ --------- 。
EMPNO UNIQUE
EMPTYPE NONUNIQUE 。
SQL> select * from emp where empno >= 2 and emp_type = 'A' ; 。
no rows selected 。
Execution Plan 。
---------------------------------------------------------- 。
0 SELECT STATEMENT Optimizer=CHOOSE 。
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP' 。
2 1 INDEX (RANGE SCAN) OF 'EMPTYPE' (NON-UNIQUE) 。
虽然EMPNO是唯一性索引,但是由于它所做的是范围比较, 等级要比非唯一性索引的等式比较低! 。
20. 强制索引失效
如果两个或以上索引具有相同的等级,你可以强制命令ORACLE优化器使用其中的一个(通过它,检索出的记录数量少) . 。
举例:
SELECT ENAME
FROM EMP
WHERE EMPNO = 7935 。
AND DEPTNO + 0 = 10 /*DEPTNO上的索引将失效*/ 。
AND EMP_TYPE || ‘’ = ‘A’ /*EMP_TYPE上的索引将失效*/ 。
这是一种相当直接的提高查询效率的办法. 但是你必须谨慎考虑这种策略,一般来说,只有在你希望单独优化几个SQL时才能采用它. 。
这里有一个例子关于何时采用这种策略, 。
假设在EMP表的EMP_TYPE列上有一个非唯一性的索引而EMP_CLASS上没有索引. 。
SELECT ENAME
FROM EMP
WHERE EMP_TYPE = ‘A’
AND EMP_CLASS = ‘X’; 。
优化器会注意到EMP_TYPE上的索引并使用它. 这是目前唯一的选择. 如果,一段时间以后, 另一个非唯一性建立在EMP_CLASS上,优化器必须对两个索引进行选择,在通常情况下,优化器将使用两个索引并在他们的结果集合上执行排序及合并. 然而,如果其中一个索引(EMP_TYPE)接近于唯一性而另一个索引(EMP_CLASS)上有几千个重复的值. 排序及合并就会成为一种不必要的负担. 在这种情况下,你希望使优化器屏蔽掉EMP_CLASS索引. 。
用下面的方案就可以解决问题. 。
SELECT ENAME
FROM EMP
WHERE EMP_TYPE = ‘A’
AND EMP_CLASS||’’ = ‘X’; 。
21. 避免在索引列上使用计算. 。
WHERE子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描. 。
举例:
低效:
SELECT …
FROM DEPT
WHERE SAL * 12 > 25000; 。
高效:
SELECT …
FROM DEPT
WHERE SAL > 25000/12; 。
这是一个非常实用的规则,请务必牢记 。
22. 自动选择索引
如果表中有两个以上(包括两个)索引,其中有一个唯一性索引,而其他是非唯一性. 。
在这种情况下,ORACLE将使用唯一性索引而完全忽略非唯一性索引. 。
举例:
SELECT ENAME
FROM EMP
WHERE EMPNO = 2326 。
AND DEPTNO = 20 ; 。
这里,只有EMPNO上的索引是唯一性的,所以EMPNO索引将用来检索记录. 。
TABLE ACCESS BY ROWID ON EMP 。
INDEX UNIQUE SCAN ON EMP_NO_IDX 。
23. 避免在索引列上使用NOT 。
通常, 我们要避免在索引列上使用NOT, NOT会产生在和在索引列上使用函数相同的 。
影响. 当ORACLE”遇到”NOT ,!=,他就会停止使用索引转而执行全表扫描. 。
举例:
低效: (这里,不使用索引) 。
SELECT …
FROM DEPT
WHERE DEPT_CODE != 0; 。
高效: (这里,使用了索引) 。
SELECT …
FROM DEPT
知道的基本就这么多了,要加分啊~~O(∩_∩)O~。
lab n.实验室,研究室
label n.标签;标记,符号。
laboratory n.实验室,研究室。
labour n.劳动;工作;劳工。
lace n.鞋带,系带;花边。
lack vi.&vi.&n.缺乏,不足。
ladder n.梯子,梯状物。
lady n.女士,夫人;贵妇人。
lag vi.走得慢 n.落后。
lake n.湖
lamb n.羔羊,小羊;羔羊肉。
lame a.跛的;瘸的,残废的。
lamp n.灯
land n.陆地;土地 vi.上岸。
landing n.上岸,登陆,着陆。
landlady n.女房东;女地主。
landlord n.地主;房东,店主。
lane n.(乡间)小路;跑道。
language n.语言,语言课程。
lantern n.提灯,灯笼。
lap n.膝部;一圈
large a.大的;巨大的
largely ad.大部分;大量地。
laser n.激光
last a.最后的 ad.最后。
last vi.持续,持久;耐久。
late a.迟的 ad.迟,晚。
lately ad.最近,不久前。
later ad.后来;过一会儿。
Latin a.拉丁的 n.拉丁语。
latter a.(两者中)后者的。
laugh vi.笑,发笑 n.笑。
laughter n.笑,笑声。
launch vt.发射,投射;发动。
laundry n.洗衣房,洗衣店。
lavatory n.盥洗室,厕所。
law n.法律,法令;法则
lawn n.草地,草坪,草场。
lawyer n.律师;法学家。
lay vt.置放;铺设;设置。
layer n.层,层次;铺设者。
layout n.布局,安排,设计。
lazy a.懒惰的,懒散的
lead vt.为…带路;领导。
lead n.铅,铅制品
leader n.领袖,领导人;首领。
leadership n.领导。
leading a.指导的;最主要的。
leaf n.叶,叶子
league n.同盟,联盟;联合会。
leak vi.漏;泄露 n.漏洞。
lean vi.倾斜,屈身;*。
leap vi.跳,跃 n.跳跃。
learn vi.&vt.学,学习。
learned a.有学问的;学术上的。
learning n.学习;学问,知识。
least a.最少的 ad.最少。
leather n.皮革;皮革制品。
leave vi.离去 vt.离开。
lecture n.&vi.演讲,讲课。
left a.左边的 ad.在左边。
leg n.腿,腿部
legal a.法律的;合法的。
legend n.传说,传奇
leisure n.空闲时间;悠闲。
lemon n.柠檬,柠檬树
lend vt.把…借给,贷(款)。
length n.长,长度;一段。
lens n.透镜,镜片;镜头。
less a.更少的 ad.更少地。
lessen vt.减少,减轻;缩小。
lesson n.功课,课;课程。
lest conj.惟恐,以免。
let vt.允许,让;使
letter n.信;证书;字母。
level n.水平面 a.水平的。
lever n.杆,杠杆;控制杆。
liable a.易于…的;可能的。
liar n.说谎的人
liberal a.心胸宽大的;慷慨的。
liberate vt.解放;释放。
liberation n.解放。
liberty n.自由;释放;许可。
librarian n.图书馆馆长。
library n.图书馆;藏书。
license n.许可;执照 vt.准许。
lick vt.舔;舔吃
lid n.盖子,盖,囊盖
lie vi.躺,平放;位于
lie vi.说谎,欺骗 n.谎话。
lieutenant n.陆军中尉;副职官员。
life n.生命;一生;寿命。
lifetime n.一生,终身。
lift vt.提起,提高 n.电梯。
light n.光,光线;灯,光源。
light a.轻的,少量的
lighten vt.照亮,使明亮。
lightly ad.轻轻地,轻松地。
lightning n.闪电,闪电放电。
like vt.喜欢;喜爱;希望。
like prep.像,如;像要。
likely a.可能的 ad.很可能。
likewise ad.同样地;也,又。
limb n.肢,臂,翼;树枝。
lime n.石灰
limit n.限度;限制;范围。
limitation n.限制;限度,局限。
limited a.有限的
line n.线;排;路线;线条。
linen n.亚麻布;亚麻织物。
liner n.班船,班机
link vt.有环连接 n.环。
lion n.狮子;勇猛的人
lip n.嘴唇
liquid n.液体 a.液体的。
liquor n.酒;溶液,液剂。
list n.表,目录 n.列举。
listen vi.听,留神听;听从。
listener n.听者,听众之一。
liter n.升(容量单位)。
literary a.文学(上)的。
literature n.文学;文献。
little a.小的;少;幼小的。
live vi.居住;活 a.活的。
lively a.活泼的;逼真的。
liver n.肝;肝脏
living a.活的 n.生活,生计。
living-room n.起居室。
load vt.装;装满 n.负载。
loaf n.一条面包,一个面包。
loan n.贷款;暂借 vt.借出。
local a.地方的;局部的。
locate vt.探明,找出,查出。
location n.位置,场所。
lock n.锁 vt.锁上,锁住。
locomotive n.火车头,机车。
lodge vi.暂住,借宿,投宿。
log n.原木,木料
logic n.逻辑,推理;逻辑性。
logical a.逻辑的;符合逻辑的。
lonely a.孤独的;荒凉的。
long a.长的;远的 ad.长久。
long vi.渴望,极想念
look vi.看,显得 n.看。
loop n.圈,环,环孔
loose a.松的;宽松的
loosen vt.解开;使松驰。
lord n.贵族;上帝,基督。
lorry n.运货汽车,卡车。
lose vt.失去;迷失;输掉。
loss n.遗失;损失;失败。
lot n.许多,大量;签,阄。
loud a.响亮的;吵闹的
loudspeaker n.扬声器,喇叭。
love vt.爱,喜欢 n.爱。
lovely a.可爱的;令人愉快的。
lover n.爱好者;情人;情侣。
low a.低的,矮的;低下的。
lower a.较低的 vt.放下。
loyal a.忠诚的,忠心的。
loyalty n.忠诚,忠心。
luck n.运气;好运,幸运。
lucky a.幸运的;吉祥的。
luggage n.行李;皮箱,皮包。
lumber n.木材;木料;制材。
lump n.团,块;肿块
lunch n.午餐,(美)便餐。
lung n.肺脏,肺
luxury n.奢侈,奢华;奢侈品。
T-bag 真名:Robert Knepper。
(1992) Gas Food Lodging。
中文《旅客》、《公路休息站》
年 代: 1992
地 区: 美国 (更多...)。
片 长: 101 min
导 演: 阿利森 安德斯 (Allison Anders)。
编 剧: 阿利森 安德斯 (Allison Anders) / Richard Peck (III)。
类 型: 爱情 / 剧情
http://www.mov99.com/movie/1999091802592_credit.html。
Robert Knepper 饰演 Dank。
扮演一个地质青年~~研究石头~。
<WEST WING>中也有参演,ms是一个警探还什么。。。
母爱光辉 (1994) Getting Out (TV)。
年 代: 1994
地 区: 美国 片 长: 100 min。
导 演: 约翰 科蒂 (John Korty)。
编 剧: Eugene Corr / Marsha Norman / Ruth Shapiro。
类 型: 剧情
别 名: 母爱光辉
主要演员:
坦迪 克罗宁 艾伦 伯斯汀 丽贝卡 德 莫妮。
色 彩: 彩色
http://fs2.cyworld.com.cn/data5/2006/08/19/103/1155987703596175_file.jpg。
(Law And Order) 《法律与秩序 》 TV。
参演...ms很少主演,不过美国电视剧能坚持6集以上的都不错了....。
profiler 《再现犯罪的人》, 电视剧。
据说影评不佳
《LOVE & SEX》
他演女孩高中的法语老师
说的是带法国口音的英语
很搞笑也很性感
罗伯特·克耐普 Robert Knepper 饰演Gerard Boussard。
http://movie.ku6.com/movie/31878/#menu。
图图
http://fs2.cyworld.com.cn/data8/2006/08/19/080/1155988080586032_file.jpg。
(Point Pleasant《天鹅人》FOX新剧目前电视台已停播。
http://www.verycd.com/groups/@g19053/30843.topic 电驴第一季下载地址。
图图
http://fs2.cyworld.com.cn/data8/2006/08/20/102/1156063902890307_file.jpg。
http://fs2.cyworld.com.cn/data7/2006/08/20/054/1156063854775921_file.jpg。
很德库拉的气质,优雅冷血
ER《急诊室的故事》也出现过
http://fs2.cyworld.com.cn/data5/2006/08/19/069/1155987869321538_file.jpg。
<Phantoms>。
扮演一警察
截然不同的表演
图图
http://fs2.cyworld.com.cn/data8/2006/08/20/023/1156066223049425_file.jpg。
找到这里的时候,发现一个网站,斯巴达...。
饰演T-Bag的Robert Knepper在美剧《Thieves》和《CSI》中都饰演过角色。
其他作品:1、Hostage 火线对峙 【2005】<IMG http://img3.mtime.com/mg/2007/51/1b5272de-f8ce-4965-90fe-c975d10f566e.jpg"。
2、"Prison Break" 越狱 【2005】
3、Species III 异种 3 【2004】
4、Absence of the Good(TV)魔鬼猎杀 【1999】
5、Phantoms 幻觉 【1998】
6、Jaded 激情的控诉 【1996】
7、Search and Destroy 狙击手 【1995】
8、Getting Out(TV)母爱光辉 【1994】
9、When the Bough Breaks 魔鬼刽子手 【1993】当树枝折断时(中)
10、Gas Food Lodging 【1992】
11、Session Man(TV)会议人 【1992】
12、Young Guns II 年轻枪手 2 【1990】少壮屠龙阵 2(台)/龙威虎将 2(港)
13、Renegades 赤色雄狼 【1989】叛徒(其他)
14、D.O.A. 死亡旋涡 【1988】零时亡点(港)
15、Made in Heaven 天上人间 【1987】/天堂制造。
16、That's Life! 生之乐章 【1986】
http://www.mtime.com/my/912679/blog/786701/ 其实他蛮可爱的..。
老者说“西天难取经。要取经,往东天去罢”意思就是往西天取经之路崎岖难行,劝唐僧止步于此,反向回东土大唐。
后来孙悟空说了自己的来历之后,老者便笑道:“你既有这样手段,西方也还去得,去得。”
(老者虽是开悟的人了,但通过与取经人的对话可知他知道前行的路上困难重重,有畏难的情绪,止步于此。)
《西游记》原著相关内容:
第二十回
黄风岭唐僧有难 半山中八戒争先。
……
那呆子纵身跳起,口里絮絮叨叨 的,挑着担子,只得死心塌地,跟着前来。早到了路旁人家门首,三藏下马,行者接了缰绳,八戒歇了行李,都伫立绿荫之下。三藏拄着九环锡杖,按按藤缠篾织斗 篷,先奔门前,只见一老者,斜倚竹床之上,口里嘤嘤的念佛。
三藏不敢高言,慢慢的叫一声:“施主,问讯了。”那老者一骨鲁跳将起来,忙敛衣襟,出门还礼 道:“长老,失迎。你自那方来的?到我寒门何故?”三藏道:“贫僧是东土大唐和尚,奉圣旨上雷音寺拜佛求经。适至宝方天晚,意投檀府告借一宵,万祈方便方 便。”那老儿摆手摇头道:“去不得,西天难取经。要取经,往东天去罢。”三藏口中不语,意下沉吟:“菩萨指道西去,怎么此老说往东行?东边那得有经?”腼 腆难言,半晌不答。
却说行者索性凶顽,忍不住,上前高叫道:“那老儿,你这们大年纪,全不晓事。我出家人远来借宿,就把这厌钝的话虎唬我。十分你家窄狭, 没处睡时,我们在树底下,好道也坐一夜,不打搅你。”
那老者扯住三藏道:“师父,你倒不言语,你那个徒弟,那般拐子脸、别颏腮、雷公嘴、红眼睛的一个痨病 魔鬼,怎么反冲撞我这年老之人!”
行者笑道:“你这个老儿,忒也没眼色!似那俊刮些儿的,叫做中看不中吃。想我老孙虽小,颇结实,皮裹一团筋哩。”那老者 道:“你想必有些手段。”行者道:“不敢夸言,也将就看得过。”
老者道:“你家居何处?因甚事削发为僧?”
行者道:“老孙祖贯东胜神洲海东傲来国花果山水 帘洞居住。自小儿学做妖怪,称名悟空,凭本事,挣了一个齐天大圣。只因不受天禄,大反天宫,惹了一场灾愆。如今脱难消灾,转拜沙门,前求正果,保我这唐朝 驾下的师父,上西天拜佛走遭,怕甚么山高路险,水阔波狂!我老孙也捉得怪,降得魔。
伏虎擒龙,踢天弄井,都晓得些儿。倘若府上有甚么丢砖打瓦,锅叫门开,老孙便能安镇。”
那老儿听得这篇言语,哈哈笑道:
“原来是个撞头化缘的熟嘴儿和尚。”行者道:“你儿子便是熟嘴!我这些时,只因跟我师父走路辛苦,还懒说话哩。”那老儿道:“若是你不辛苦,不懒说话,好道活活的聒杀我!你既有这样手段,西方也还去得,去得。你一行几众?请至茅舍里安宿。”
MySQL 5.5的发布带来了许多增强的功能,虽然已经报道了很多增强功能,如半同步复制,但大家却忽略了分区方面的增强,有时甚至还对其真正意义产生了误解,在这篇文章中,我们希望解释一下这些很酷的增强,特别是我们大多数人还没有完全理解的地方。51CTO向您推荐《MySQL数据库入门与精通教程》。
非整数列分区
任何使用过分区的人应该都遇到过不少问题,特别是面对非整数列分区时,MySQL 5.1只能处理整数列分区,如果你想在日期或字符串列上进行分区,你不得不使用函数对其进行转换。
MySQL 5.5中新增了两类分区方法,RANG和LIST分区法,同时在新的函数中增加了一个COLUMNS关键词。我们假设有这样一个表:
1. CREATE TABLE expenses ( 。
2. expense_date DATE NOT NULL, 。
3. category VARCHAR(30), 。
4. amount DECIMAL (10,3) 。
5. );
如果你想使用MySQL 5.1中的分区类型,那你必须将类型转换成整数,需要使用一个额外的查找表,到了MySQL 5.5中,你可以不用再进行类型转换了,如:
1. ALTER TABLE expenses 。
2. PARTITION BY LIST COLUMNS (category) 。
3. (
4. PARTITION p01 VALUES IN ( 'lodging', 'food'), 。
5. PARTITION p02 VALUES IN ( 'flights', 'ground transportation'), 。
6. PARTITION p03 VALUES IN ( 'leisure', 'customer entertainment'), 。
7. PARTITION p04 VALUES IN ( 'communications'), 。
8. PARTITION p05 VALUES IN ( 'fees') 。
9. );
这样的分区语句除了更加易读外,对数据的组织和管理也非常清晰,上面的例子只对category列进行分区。
在MySQL 5.1中使用分区另一个让人头痛的问题是date类型(即日期列),你不能直接使用它们,必须使用YEAR或TO_DAYS转换这些列,如:
1. /* 在MySQL 5.1中*/ 。
2. CREATE TABLE t2 。
3. (
4. dt DATE
5. )
6. PARTITION BY RANGE (TO_DAYS(dt)) 。
7. (
8. PARTITION p01 VALUES LESS THAN (TO_DAYS('2007-01-01')), 。
9. PARTITION p02 VALUES LESS THAN (TO_DAYS('2008-01-01')), 。
10. PARTITION p03 VALUES LESS THAN (TO_DAYS('2009-01-01')), 。
11. PARTITION p04 VALUES LESS THAN (MAXVALUE)); 。
12.
13. SHOW CREATE TABLE t2 \G 。
14. *************************** 1. row *************************** 。
15. Table: t2 。
16. Create Table: CREATE TABLE `t2` ( 。
17. `dt` date DEFAULT NULL 。
18. ) ENGINE=MyISAM DEFAULT CHARSET=latin1 。
19. /*!50100 PARTITION BY RANGE (TO_DAYS(dt)) 。
20. (PARTITION p01 VALUES LESS THAN (733042) ENGINE = MyISAM, 。
21. PARTITION p02 VALUES LESS THAN (733407) ENGINE = MyISAM, 。
22. PARTITION p03 VALUES LESS THAN (733773) ENGINE = MyISAM, 。
23. PARTITION p04 VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */ 。
看上去非常糟糕,当然也有变通办法,但麻烦确实不少。使用YEAR或TO_DAYS定义一个分区的确让人费解,查询时不得不使用赤裸列,因为加了函数的查询不能识别分区。
但在MySQL 5.5中情况发生了很大的变化,现在在日期列上可以直接分区,并且方法也很简单。
1. /*在MySQL 5.5中*/ 。
2. CREATE TABLE t2 。
3. (
4. dt DATE
5. )
6. PARTITION BY RANGE COLUMNS (dt) 。
7. (
8. PARTITION p01 VALUES LESS THAN ('2007-01-01'), 。
9. PARTITION p02 VALUES LESS THAN ('2008-01-01'), 。
10. PARTITION p03 VALUES LESS THAN ('2009-01-01'), 。
11. PARTITION p04 VALUES LESS THAN (MAXVALUE)); 。
12.
13. SHOW CREATE TABLE t2 \G 。
14. *************************** 1. row *************************** 。
15. Table: t2 。
16. Create Table: CREATE TABLE `t2` ( 。
17. `dt` date DEFAULT NULL 。
18. ) ENGINE=MyISAM DEFAULT CHARSET=latin1 。
19. /*!50500 PARTITION BY RANGE COLUMNS(dt) 。
20. (PARTITION p01 VALUES LESS THAN ('2007-01-01') ENGINE = MyISAM, 。
21. PARTITION p02 VALUES LESS THAN ('2008-01-01') ENGINE = MyISAM, 。
22. PARTITION p03 VALUES LESS THAN ('2009-01-01') ENGINE = MyISAM, 。
23. PARTITION p04 VALUES LESS THAN (MAXVALUE) ENGINE = MyISAM) */ 。
在这里,通过函数定义和通过列查询之间没有冲突,因为是按列定义的,我们在定义中插入的值是保留的。
多列分区
COLUMNS关键字现在允许字符串和日期列作为分区定义列,同时还允许使用多个列定义一个分区,你可能在官方文档中已经看到了一些例子,如: 。
1. CREATE TABLE p1 ( 。
2. a INT,
3. b INT,
4. c INT
5. )
6. PARTITION BY RANGE COLUMNS (a,b) 。
7. (
8. PARTITION p01 VALUES LESS THAN (10,20), 。
9. PARTITION p02 VALUES LESS THAN (20,30), 。
10. PARTITION p03 VALUES LESS THAN (30,40), 。
11. PARTITION p04 VALUES LESS THAN (40,MAXVALUE), 。
12. PARTITION p05 VALUES LESS THAN (MAXVALUE,MAXVALUE) 。
13. );
14.
15. CREATE TABLE p2 ( 。
16. a INT,
17. b INT,
18. c INT
19. )
20. PARTITION BY RANGE COLUMNS (a,b) 。
21. (
22. PARTITION p01 VALUES LESS THAN (10,10), 。
23. PARTITION p02 VALUES LESS THAN (10,20), 。
24. PARTITION p03 VALUES LESS THAN (10,30), 。
25. PARTITION p04 VALUES LESS THAN (10,MAXVALUE), 。
26. PARTITION p05 VALUES LESS THAN (MAXVALUE,MAXVALUE) 。
27. )
同样还有PARTITION BY RANGE COLUMNS (a,b,c)等其它例子。由于我很长时间都在使用MySQL 5.1的分区,我对多列分区的含义不太了解,LESS THAN (10,10)是什么意思?如果下一个分区是LESS THAN (10,20)会发生什么?相反,如果是(20,30)又会如何?
所有这些问题都需要一个答案,在回答之前,他们需要更好地理解我们在做什么。
开始时可能有些混乱,当所有分区有一个不同范围的值时,实际上,它只是在表的一个列上进行了分区,但事实并非如此,在下面的例子中:
1. CREATE TABLE p1_single ( 。
2. a INT,
3. b INT,
4. c INT
5. )
6. PARTITION BY RANGE COLUMNS (a) 。
7. (
8. PARTITION p01 VALUES LESS THAN (10), 。
9. PARTITION p02 VALUES LESS THAN (20), 。
10. PARTITION p03 VALUES LESS THAN (30), 。
11. PARTITION p04 VALUES LESS THAN (40), 。
12. PARTITION p05 VALUES LESS THAN (MAXVALUE) 。
13. );
它和前面的表p1不一样,如果你在表p1中插入(10,1,1),它将会进入第一个分区,相反,在表p1_single中,它将会进入第二个分区,其原因是(10,1)小于(10,10),如果你仅仅关注第一个值,你还没有意识到你在比较一个元组,而不是一个单一的值。
现在我们来分析一下最难懂的地方,当你需要确定某一行应该放在哪里时会发生什么?你是如何确定类似(10,9) < (10,10)这种运算的值的?答案其实很简单,当你对它们进行排序时,使用相同的方法计算两条记录的值。
1. a=10
2. b=9
3. (a,b) < (10,10) ? 。
4.
5. # evaluates to: 。
6.
7. (a < 10) 。
8. OR
9. ((a = 10) AND ( b < 10)) 。
10.
11. # which translates to: 。
12.
13. (10 < 10) 。
14. OR
15. ((10 = 10) AND ( 9 < 10)) 。
如果有三列,表达式会更长,但不会更复杂。你首先在第一个项目上测试小于运算,如果有两个或更多的分区与之匹配,接着就测试第二个项目,如果不止一个候选分区,那还需要测试第三个项目。
下图所显示的内容表示将遍历三条记录插入到使用以下代码定义的分区中:
(10,10),
(10,20),
(10,30),
(10, MAXVALUE)
图 2 元组比较。当第一个值小于分区定义的第一个范围时,那么该行将属于这里了。
图 3 元组比较。当第一个值等于分区定义的第一个范围,我们需要比较第二个项目,如果它小于第二个范围,那么该行将属于这里了。
图 4 元组比较。当第一个值和第二个值等于他们对应的范围时,如果元组不小于定义的范围,那么它就不属于这里,继续下一步。
图 5 元组比较。在下一个范围时,第一个项目是等于,第二个项目是小于,因此元组更小,那么该行就属于这里了。
在这些图的帮助下,我们对插入一条记录到多列分区表的步骤有了更深的了解,这些都是理论上的,为了帮助你更好地掌握新功能,我们再来看一个更高级一点的例子,对于比较务实的读者更有意义,下面是表的定义脚本:
1. CREATE TABLE employees ( 。
2. emp_no int(11) NOT NULL, 。
3. birth_date date NOT NULL, 。
4. first_name varchar(14) NOT NULL, 。
5. last_name varchar(16) NOT NULL, 。
6. gender char(1) DEFAULT NULL, 。
7. hire_date date NOT NULL 。
8. ) ENGINE=MyISAM 。
9. PARTITION BY RANGE COLUMNS(gender,hire_date) 。
10. (PARTITION p01 VALUES LESS THAN ('F','1990-01-01') , 。
11. PARTITION p02 VALUES LESS THAN ('F','2000-01-01') , 。
12. PARTITION p03 VALUES LESS THAN ('F',MAXVALUE) , 。
13. PARTITION p04 VALUES LESS THAN ('M','1990-01-01') , 。
14. PARTITION p05 VALUES LESS THAN ('M','2000-01-01') , 。
15. PARTITION p06 VALUES LESS THAN ('M',MAXVALUE) , 。
16. PARTITION p07 VALUES LESS THAN (MAXVALUE,MAXVALUE) 。
和上面的例子不同,这个例子更好理解,第一个分区用来存储雇佣于1990年以前的女职员,第二个分区存储股用于1990-2000年之间的女职员,第三个分区存储所有剩下的女职员。对于分区p04到p06,我们策略是一样的,只不过存储的是男职员。最后一个分区是控制情况。
看完后你可能要问,我怎么知道某一行存储在那个分区中的?有两个办法,第一个办法是使用与分区定义相同的条件作为查询条件进行查询。