2008-09-18 5 views
17

(잠재적으로 중복되는) WHERE 절이 포함 된 매우 큰 SQL 쿼리를 만드는 것이 특히 바람직하지 않습니까? 그것은 보인다SQL 쿼리 (특히 MySQL)의 실제 길이 제한

SELECT * 
FROM 4e_magic_items 
INNER JOIN 4e_magic_item_levels 
    ON 4e_magic_items.id = 4e_magic_item_levels.itemid 
INNER JOIN 4e_monster_sources 
    ON 4e_magic_items.source = 4e_monster_sources.id 
WHERE (itemlevel BETWEEN 1 AND 30) 
    AND source!=16 AND source!=2 AND source!=5 
    AND source!=13 AND source!=15 AND source!=3 
    AND source!=4 AND source!=12 AND source!=7 
    AND source!=14 AND source!=11 AND source!=10 
    AND source!=8 AND source!=1 AND source!=6 
    AND source!=9 AND type!='Arms' AND type!='Feet' 
    AND type!='Hands' AND type!='Head' 
    AND type!='Neck' AND type!='Orb' 
    AND type!='Potion' AND type!='Ring' 
    AND type!='Rod' AND type!='Staff' 
    AND type!='Symbol' AND type!='Waist' 
    AND type!='Wand' AND type!='Wondrous Item' 
    AND type!='Alchemical Item' AND type!='Elixir' 
    AND type!='Reagent' AND type!='Whetstone' 
    AND type!='Other Consumable' AND type!='Companion' 
    AND type!='Mount' AND (type!='Armor' OR (false)) 
    AND (type!='Weapon' OR (false)) 
ORDER BY type ASC, itemlevel ASC, name ASC 

가 충분히 일할 수 :

는 예를 들어, 다음은이 프로그램이 생성을 위해 가능한 최대 쿼리 수 있어야 모든 전원이 꺼져로 내 웹 응용 프로그램에서 생성 한 쿼리,이다 하지만 특히 트래픽이 많지 않아 (하루에 수백 개의 조회수가 발생 함) 중복성 등을 제거하기 위해 쿼리를 최적화하고 최적화하려는 노력을 기울일만한 가치가 있는지 궁금합니다.

+0

1. 질문에 대답 해 주셔서 감사합니다 실제 똑바로 대답이 없다, 그래서 이것이 내가 생각하는 서버는 조정의 유일한 진짜 한계 질의의 크기가 나에게 문제가되어서는 안된다. 2. SQL 서식 지정에 대한 정보 주셔서 감사합니다. 나는 그것에 익숙하지 않고 내가 모르는 많은 트릭이있다. (예를 들어, "타입이 없다 (...)") 3. 부록과 같이, 이것은 PHP/MySQL 어플리케이션이다. – Asmor

+1

유용하다. 온라인 SQL 포맷터 : http://www.sqlinform.com/ – micahwittman

+0

당신이 웹 사이트를 사용하려고 할 때 느린가요? 하루에 몇 백 개 안타가 있다면 걱정할 필요가 없습니다. 트래픽이 증가 할 것으로 예상합니까? 얼마나? 시간 낭비하지 않으면 사이트를 미래 보장 할 수 있습니다. 그러나 쿼리를 실행하는 데 걸리는 시간보다 더 큰 중복을 프로그램 적으로 찾아서 제거하는 데 걸리는 시간은 얼마입니까? –

답변

19

쿼리를 읽으면 RPG를 재생하고 싶습니다.

이것은 너무 길지 않습니다. 그들이 형식이 잘 잡혀있는 한 실제 한계는 약 100 줄이라고 말하고 싶습니다. 그 후에는 눈을 건너지 않도록 하위 쿼리를보기로 깨는 것이 좋습니다.

저는 1000 개 이상의 쿼리를 사용하여 디버깅하기가 어렵습니다.

그런데 다시 포맷 한 버전을 제안 해 주시겠습니까? 이것은 주로 서식의 중요성을 입증하기위한 것입니다. 나는 이것이 더 이해하기 쉬울 것이라고 믿는다.

select * 
from 
    4e_magic_items mi 
,4e_magic_item_levels mil 
,4e_monster_sources ms 
where mi.id = mil.itemid 
    and mi.source = ms.id 
    and itemlevel between 1 and 30 
    and source not in(16,2,5,13,15,3,4,12,7,14,11,10,8,1,6,9) 
    and type not in(
        'Arms' ,'Feet' ,'Hands' ,'Head' ,'Neck' ,'Orb' , 
        'Potion' ,'Ring' ,'Rod' ,'Staff' ,'Symbol' ,'Waist' , 
        'Wand' ,'Wondrous Item' ,'Alchemical Item' ,'Elixir' , 
        'Reagent' ,'Whetstone' ,'Other Consumable' ,'Companion' , 
        'Mount' 
       ) 
    and ((type != 'Armor') or (false)) 
    and ((type != 'Weapon') or (false)) 
order by 
    type asc 
,itemlevel asc 
,name asc 

/* 
Some thoughts: 
============== 
0 - Formatting really matters, in SQL even more than most languages. 
1 - consider selecting only the columns you need, not "*" 
2 - use of table aliases makes it short & clear ("MI", "MIL" in my example) 
3 - joins in the WHERE clause will un-clutter your FROM clause 
4 - use NOT IN for long lists 
5 - logically, the last two lines can be added to the "type not in" section. 
    I'm not sure why you have the "or false", but I'll assume some good reason 
    and leave them here. 
*/ 
+1

실제로 조인을 사용하면 특히 적절한 색인을 사용하여 작업 속도를 높일 수 있습니다. 그 이유는 모든 절이 WHERE에 있으면 mysql이 모든 데이터를 가져 와서 필터링하기 때문입니다. 적절한 조인을 사용하면 필요한 데이터 만 선택하게되며, 필터링을 빨리 수행하면 크기가 몇 배 더 작아 질 수 있습니다. – Aeon

+1

오, 그리고 ... (type! = Armour 'OR (false)) 은 누락되었지만 어느 쪽이든 true로 평가 될 것입니다. 결과 세트에 영향을 미치므로 실제로 필요하지 않습니다. – Aeon

+1

갑옷 (및 무기)이 유형별로 추가 필터링되기 때문입니다. 예를 들어 옷감과 숨기기를 선택하면 다음과 같이됩니다. (type! = 'Armour'OR ('H'와 같은 'C'OR 제한 사항과 같은 거짓 또는 제한 사항)) 페이지에 "또는 무엇이든 ' "괄호 안에는 거짓이 필요하다. – Asmor

0

대부분의 데이터베이스는이 문제를 피하기 위해 저장 프로 시저를 지원합니다. 코드가 실행 속도가 빠르고 읽기 쉽기 때문에 컴파일 시간을 줄이려면 코드를 변경하지 않아도됩니다.

대안은 클라이언트 연결 당 한 번만의 히트를 얻을 수 있도록 준비된 문을 사용하고

15

기본 5.0 서버 제한 "1메가바이트"까지 구성 할 각 호출에 매개 변수 만 전달하는 것입니다 1GB.

이 설정은 클라이언트와 서버 모두에서 max_allowed_packet 설정을 통해 이루어지며, 유효한 제한은 두 서버의 임대인입니다.

주의 사항 :

  • 그것은이 "패킷"제한은 SQL 문에서 문자로 직접 매핑되지 않습니다 가능성이 높습니다. 클라이언트 내 문자 인코딩, 일부 패킷 메타 데이터 등을 고려해야합니다.
0

필드가 값이 없음을 '꺼짐'으로 가정하고 있습니까?

뭔가가 아닌지 확인하는 것 외에도 필드가 null인지 여부도 확인할 수 없습니다. 또는 필드를 '꺼짐'으로 설정하고 입력 또는 '꺼짐'과 같은지 확인하십시오.

1

실용적인 관점에서 볼 때 필자는 일반적으로 10 줄 이상을 써서 (각 절/조건을 별도의 줄에 두는) 끝내기 쉬운 SELECT를 너무 쉽게 유지할 수 있다고 생각합니다. 이 시점에서, 아마도 일종의 저장 프로 시저로 수행해야합니다. 또는 동일한 개념을 표현하는 더 좋은 방법을 찾으려고 노력해야합니다. 중간 쿼리를 작성하여 자주 쿼리하는 것처럼 보이는 관계를 캡처 할 수 있습니다.

귀하의 마일리지가 달라질 수 있으며 예외적으로 긴 검색어가있을 수 있습니다. 하지만 내 어림짐작은 10 줄입니다.

(약간 부적절한 SQL) :

SELECT x, y, z 
FROM a, b 
WHERE fiz = 1 
AND foo = 2 
AND a.x = b.y 
AND b.z IN (SELECT q, r, s, t 
      FROM c, d, e 
      WHERE c.q = d.r 
       AND d.s = e.t 
       AND c.gar IS NOT NULL) 
ORDER BY b.gonk 

이 아마 너무 큰; 그러나 최적화는 문맥에 크게 의존합니다.

쿼리가 길고 복잡할수록 유지 관리가 어려워집니다.

3

SELECT @@ global.max_allowed_packet