> 데이터 베이스 > MySQL 튜토리얼 > SQL 문 최적화에 대한 간략한 토론

SQL 문 최적화에 대한 간략한 토론

伊谢尔伦
풀어 주다: 2016-12-03 11:07:27
원래의
961명이 탐색했습니다.

(1) 가장 효율적인 테이블 이름 순서 선택(규칙 기반 SEO/' target='_blank'> 최적화 프로그램에서만 유효함):
ORACLE의 파서는 오른쪽에서 왼쪽 순서로 테이블을 처리합니다. FROM 절에 마지막으로 작성된 테이블(기본 테이블 구동 테이블)이 먼저 처리됩니다. FROM 절에 여러 테이블이 포함되어 있는 경우 가장 작은 수의 테이블을 기본 테이블로 선택해야 합니다. 쿼리에 조인할 테이블이 3개 이상인 경우 교차 테이블을 기본 테이블로 선택해야 합니다. 크로스 테이블은 다른 테이블이 참조하는 테이블을 참조합니다.
(2) WHERE의 연결 순서. 조항 . :
ORACLE은 WHERE 절을 구문 분석하기 위해 상향식 순서를 사용합니다. 이 원칙에 따라 테이블 간의 연결은 다른 WHERE 조건보다 먼저 작성되어야 하며 최대 레코드 수를 필터링할 수 있는 조건은 WHERE 절에 작성되어야 합니다. .
(3) SELECT 절에 '*' 사용을 피하세요.
ORACLE은 구문 분석 중에 '*'를 차례로 모든 열 이름으로 변환합니다. Dictionary , 이는 더 많은 시간이 소요됨을 의미합니다
(4) get='_blank'>데이터베이스에 대한 액세스 수를 줄입니다:
ORACLE은 내부적으로 많은 작업을 수행합니다: SQL 문 구문 분석, 인덱스 활용도 추정, 바인딩 변수, 데이터 블록 읽기 등
(5) SQL*Plus, SQL*Forms 및 Pro*C에서 ARRAYSIZE 매개변수를 재설정하여 각 get='_blank'> 권장값은 200입니다
(6) 처리 시간을 단축하려면 DECODE 기능을 사용하세요.
동일한 레코드를 반복적으로 스캔하거나 동일한 테이블을 반복적으로 연결하는 것을 방지하려면 DECODE 기능을 사용하세요.
(7) 간단하고, uncorlated get='_blank'>데이터베이스 액세스:
간단한 get='_blank'>데이터베이스 쿼리 문이 여러 개 있는 경우 이를 하나의 쿼리로 결합할 수 있습니다(서로 관계가 없더라도)
(8) 중복 레코드 삭제:
중복 레코드를 삭제하는 가장 효율적인 방법(ROWID를 사용하므로) 예:
DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID)
FROM EMP 복구 가능한 정보 COMMIT 트랜잭션이 없으면 ORACLE은 데이터를 삭제 전 상태(정확히는 삭제 명령이 실행되기 전 상태)로 복원합니다. 세그먼트는 더 이상 복구 가능한 데이터를 저장하지 않습니다. 명령이 실행되면 데이터를 복구할 수 없습니다. 따라서 리소스가 거의 호출되지 않으며 실행 시간이 매우 짧습니다. (번역자 참고 사항: TRUNCATE는 전체를 삭제할 때만 적용됩니다. 테이블, TRUNCATE는 DML이 아닌 DDL입니다)
(10) COMMIT를 최대한 사용하세요:
프로그램 내에서는 가능하면 COMMIT를 많이 사용하세요. 그러면 프로그램의 성능이 향상되고 수요가 늘어날 것입니다. COMMIT에 의해 해제된 리소스로 인해 감소됩니다:
COMMIT 리소스에 의해 해제됨:
a. 롤백 세그먼트에서 데이터를 복구하는 데 사용되는 정보.
b 프로그램 문에 의해 획득된 잠금
c. redo 로그 버퍼에서
d. ORACLE은 3개 리소스 사이에서 위의 내부 비용을 관리합니다.
(11) HAVING 절을 Where 절로 바꿉니다.
HAVING 절을 사용하지 마세요. HAVING은 이후의 결과 집합만 필터링합니다. 모든 레코드가 검색되었습니다. 이 처리에는 정렬, 합계 및 기타 작업이 필요합니다. WHERE 절을 통해 레코드 수를 제한할 수 있으면 이 영역(비Oracle의 경우)에 대한 오버헤드를 줄일 수 있습니다. 조건을 추가할 수 있는 3개의 절이 있는데, on is 먼저 실행되고, where, have가 마지막에 실행됩니다. 먼저 조건에 맞지 않는 레코드를 필터링하기 때문에 중간 작업에서 처리할 데이터를 줄일 수 있습니다. 논리적으로 말하면 가장 빨라야 하며, 합산하기 전에 데이터를 필터링하고 두 테이블이 조인될 때만 on을 사용하므로, 테이블이 사용될 때 where 및 보유가 있는 것보다 더 빨라야 합니다. 비교. 단일 테이블 쿼리 통계의 경우 필터링할 조건에 계산할 필드가 포함되지 않으면 러시모어 기술을 사용할 수 있지만 사용할 수 없는 경우를 제외하고 결과는 동일하며 후자가 속도가 느립니다. 계산된 필드를 포함한다는 것은 계산 전에 이 필드의 값이 불확실하다는 것을 의미합니다. 이전 기사에 작성된 워크플로에 따르면 계산 전에 작업이 완료되는 반면 계산 후에 완료되는 작업이 수행됩니다. 이 경우 둘의 결과는 달라집니다. 다중 테이블 조인 쿼리에서는 on이 where보다 먼저 적용됩니다. 시스템은 먼저 각 테이블 간의 연결 조건을 기반으로 여러 테이블을 임시 테이블로 결합한 다음 위치별로 필터링한 다음 계산 후 보유로 필터링합니다. 필터 조건이 올바른 역할을 하도록 하려면 먼저 조건이 언제 적용되어야 하는지 이해한 다음 거기에 배치하기로 결정해야 한다는 것을 알 수 있습니다.
(12) 테이블의 쿼리를 줄입니다.
포함 하위 쿼리 SQL 문에서는 테이블 쿼리 수를 줄이는 데 특별한 주의를 기울여야 합니다. 예:
SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT
TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)
( 13) 내부 함수를 통한 SQL 효율성 향상:
복잡한 SQL은 실행 효율성을 저하시키는 경우가 많습니다. 위의 함수를 사용하여 문제를 해결하는 방법을 숙지할 수 있다는 것은 실제 작업에서 매우 의미가 있습니다
( 14) 테이블 별칭 사용:
하나의 SQL 문에서 여러 테이블을 연결하는 경우, 테이블의 별칭을 사용하고 각 열에 별칭을 붙이면 파싱 시간을 단축하고 열 모호함으로 인한 구문 오류를 줄일 수 있습니다.
(15) IN 대신 EXISTS를 사용하고, NOT IN 대신 NOT EXISTS를 사용하세요.
기본 테이블을 기반으로 하는 많은 쿼리에서는 조건을 충족하기 위해 다른 테이블을 조인해야 하는 경우가 많습니다. 이 경우 EXISTS( 또는 NOT을 사용하세요. EXISTS)는 일반적으로 하위 쿼리에서 NOT IN 절을 사용하여 내부 정렬 및 병합을 수행합니다(테이블이 전체 테이블 순회를 수행하기 때문에). NOT IN 사용을 피하기 위해 외부 조인 또는 NOT EXISTS로 다시 작성할 수 있습니다.
예:
(효율적) SELECT * FROM EMP(기본 테이블) WHERE EMPNO > 0 AND EXISTS (SELECT 'X' FROM; DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = 'MELB')
(비효율적) SELECT * FROM EMP(기본 테이블) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = 'MELB')
(16) '비효율적인 실행' SQL 문 식별:
현재 SQLseo/' target='_blank'>에 대한 다양한 최적화가 있지만 그래픽 도구는 무한하지만 자신만의 SQL 도구를 작성하는 것이 항상 가장 좋습니다. 문제 해결 방법:
SELECT EXECUTIONS, DISK_READS, BUFFER_GETS,
ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio ,
ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,
SQL_TEXT
V$SQLAREA
WHERE EXECUTIONS>0
AND BUFFER_GETS > 0
AND (BUFFER_GETS-DISK_READS)/ BUFFER_GETS < 0.8
ORDER BY 4 DESC;
(17) 효율성 향상을 위한 인덱스:
인덱스는 데이터 검색 효율성을 높이기 위해 사용되는 테이블의 개념적 부분으로, ORACLE은 복잡한 자체 균형 B-트리 구조를 사용합니다. 일반적으로 인덱스를 통해 데이터를 쿼리하는 것이 전체 쿼리보다 빠릅니다. ORACLE이 쿼리 및 업데이트 문을 실행하기 위한 최적의 경로를 찾아낼 때 ORACLEseo/' target='_blank'> 마찬가지로 인덱스를 사용하면 여러 테이블을 결합할 때 효율성이 향상됩니다. 기본 키의 고유성 확인을 제공한다는 것입니다. LONG 또는 LONG RAW 데이터 유형을 사용하면 거의 모든 열을 인덱싱할 수 있습니다. 일반적으로 인덱스를 사용하는 것은 큰 테이블에서 특히 효과적입니다. 물론 인덱스 쿼리를 사용하더라도 인덱스를 사용하면 효율성이 향상될 수도 있습니다. 효율성을 높일 수는 있지만 비용에도 주의해야 합니다. 인덱스는 테이블에 레코드가 추가되거나 삭제되거나 인덱스 열이 수정될 때마다 인덱스 자체도 수정됩니다. 각 레코드의 INSERT, DELETE 및 UPDATE에는 디스크 I/O 비용이 4~5배 더 많이 소요됩니다. 인덱스에는 추가 저장 공간과 처리가 필요하기 때문에 이러한 불필요한 인덱스는 실제로 쿼리 응답 시간을 단축시킵니다. 정기적인 인덱스 재구축이 필요합니다.:
ALTER INDEX REBUILD
18) DISTINCT를 EXISTS로 교체:
일대다 테이블 정보(부서 테이블, 직원 테이블 등)가 포함된 쿼리를 제출하는 경우 , SELECT 절에 DISTINCT를 사용하지 마세요. 일반적으로 EXIST를 사용하면 하위 쿼리 조건이 충족되면 즉시 결과를 반환하므로 EXISTS를 사용하면 쿼리가 더 빨라집니다. 비효율적):
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);
(19) server/' target='_blank'> oracle은 항상 server/' target=을 구문 분석하므로 sql 문은 대문자입니다. 첫 번째 '_blank'>sql 문, 소문자를 대문자로 변환한 후
실행
(20) 자바 코드에서 문자열 연결은 커넥터 "+"를 최대한 적게 사용하세요!
(21) 인덱스 열에 NOT 사용 금지
우리는 인덱스 열에 NOT을 사용하지 않기를 원합니다. NOT은 인덱스 열에 함수를 사용하는 것과 동일한 영향을 미칩니다. 인덱스를 사용하여 전체 테이블 스캔을 수행합니다.
(22) 인덱스 열에 대한 계산을 사용하지 마세요.
WHERE 절에서 인덱스 열이 함수의 일부인 경우. seo/' target='_blank'>최적화 프로그램은 인덱스를 사용하지 않고 전체 테이블 스캔을 사용합니다.
예:
비효율적:
SELECT … DEPT WHERE SAL * 12 > 25000;
효율적:
SELECT … FROM DEPT WHERE SAL > 25000/12;
( 23 )>
대신 >=를 사용하세요.
SELECT * FROM EMP WHERE DEPTNO >=4
비효율적:
SELECT * FROM EMP WHERE DEPTNO >3
둘 다 차이점은 다음과 같습니다. 이전 DBMS는 DEPT가 4인 첫 번째 레코드로 직접 점프하는 반면, 후자는 먼저 DEPTNO=3인 레코드를 찾아 DEPT가 3보다 큰 첫 번째 레코드로 스캔합니다.
(24) UNION 대체 사용 OR(인덱스 열에 적용 가능)
일반적으로 WHERE 절에서 OR을 대체하기 위해 UNION을 사용하면 더 나은 결과를 얻을 수 있습니다. 인덱스 열에 OR을 사용하면 전체 테이블 스캔이 발생합니다. 위 규칙은 여러 인덱스 열에만 유효합니다. 인덱싱되지 않은 열이 있는 경우 OR을 선택하지 않으므로 쿼리 효율성이 저하될 수 있습니다.
FROM LOCATION
WHERE LOC_ID = 10
UNION
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE REGION = “MELBOURNE”
비효율적:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10 OR REGION = “MELBOURNE”
OR을 꼭 사용해야 한다면 레코드 수가 가장 적은 인덱스 열을 반환하여 맨 앞에 써야 합니다.
( 25) IN을 OR
으로 대체하세요. 이는 간단하고 기억하기 쉬운 규칙이지만, ORACLE8i에서는 둘의 실행 경로가 동일한 것으로 보입니다.
비효율적:
선택…. LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30
효율적
선택… LOC_IN IN(10,20,30) 위치에서;
(26) 인덱스 열에 IS NULL 및 IS NOT NULL을 사용하지 마세요.
인덱스에 Null 허용 열을 사용하지 않으면 ORACLE이 인덱스를 사용할 수 없습니다. 단일 열 인덱스의 경우 열에 Null 값이 포함되어 있으면 해당 레코드가 인덱스에 존재하지 않습니다. 복합 인덱스의 경우 각 열이 Null이면 하나 이상의 열이라도 해당 레코드가 인덱스에 존재하지 않습니다. null이 아닌 경우 해당 레코드가 인덱스에 존재합니다. 예: 테이블의 A, B 열에 고유 인덱스가 구축되어 있고 A, B 값이 (123, null)인 레코드가 테이블에 있는 경우 ORACLE은 동일한 A를 가진 다음 레코드를 허용하지 않습니다. 및 B 값(123, null) 레코드(삽입). 그러나 모든 인덱스 열이 null인 경우 ORACLE은 전체 키 값을 null로 간주하므로 null은 1000개의 레코드를 삽입할 수 있습니다. 동일한 키 값이며 물론 모두 null입니다. 인덱스 열에 null 값이 없기 때문에 WHERE 절에서 인덱스 열의 null 값 비교로 인해 ORACLE이 인덱스를 비활성화하게 됩니다.
비효율성 : (인덱스 유효하지 않음)
SELECT … DEPT_CODE가 NULL이 아닌 DEPARTMENT에서;
효율적: (인덱스 유효함)
SELECT … DEPARTMENT WHERE DEPT_CODE >=0;
(27) 항상 다음을 사용합니다. 인덱스의 첫 번째 열:
인덱스가 여러 열에 설정된 경우 최적화 프로그램은 첫 번째 열(선행 열)이 where 절에서 참조되는 경우에만 인덱스를 사용하도록 선택합니다. 이는 또한 간단하지만 중요합니다. 규칙에 따라 인덱스의 두 번째 열만 참조되는 경우 seo/' target='_blank'> 최적화 프로그램은 전체 테이블 스캔을 사용하고 인덱스를 무시합니다.
28) UNION을 UNION-ALL로 교체합니다(가능한 경우). ):
SQL 문에 UNION 두 개의 쿼리 결과 집합이 필요한 경우 두 결과 집합은 UNION-ALL 방식으로 병합된 다음 최종 결과를 출력하기 전에 정렬됩니다. 이렇게 UNION 대신 UNION ALL을 사용하면 됩니다. 결과적으로 정렬이 더 이상 필요하지 않습니다. UNION ALL은 두 결과 세트에 동일한 레코드를 반복적으로 출력하므로 비즈니스에 따라 UNION ALL 사용의 타당성을 분석해야 합니다. UNION은 정렬을 설정합니다. 이 작업은 SORT_AREA_SIZE 메모리를 사용합니다. 이 메모리의 최적화도 매우 중요합니다. 다음 SQL을 사용하여 정렬 소비를 쿼리할 수 있습니다.
비효율성:
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_ DATE = '31 -DEC-95'
효율적:
ACCT_NUM, BALANCE_AMT
DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION ALL
SELECT ACCT_NUM, BALANCE_AMT
DEBIT_TRANSACTIONS
WHERE TRAN_D 먹었다 = '31-DEC-95'
(29) ORDER BY를 WHERE로 대체:
ORDER BY 절은 두 가지 엄격한 조건에서만 인덱스를 사용합니다.
ORDER BY ORDER BY의 모든 열은 동일한 인덱스를 사용하고 인덱스의 순서를 유지합니다.
ORDER BY의 모든 열을 지정해야 합니다

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿