문제

SQL 쿼리가 발행 될 때마다 다음 점검을 실행하는 일반적인 DB 쿼리 기능이 있습니다.

  1. if (preg_match('~^(?:UPDATE|DELETE)~i', $query) === 1)
  2. if (preg_match('~^(?:UPDATE|DELETE)~iS', $query) === 1)
  3. if ((stripos($query, 'UPDATE') === 0) || (stripos($query, 'DELETE') === 0))

나는 단순한 것을 안다 strpos() 전화는 a보다 훨씬 빠릅니다 preg_match(), 그러나 내가 전화 한 이후로 strIpos() 두 배 나는 어느 것이 더 잘 수행되어야하는지 잘 모르겠습니다.

그만큼 S 두 번째 옵션의 패턴 수정자는 또한 매뉴얼에서 내 머리에 약간의 혼란을 가져옵니다.

패턴이 여러 번 사용될 때, 일치하는 데 걸리는 시간을 가속화하기 위해 분석하는 데 더 많은 시간을 할애 할 가치가 있습니다. 이 수정자가 설정되면이 추가 분석이 수행됩니다. 현재, 패턴을 연구하는 것은 단일 고정 된 시작 문자가없는 고정되지 않은 패턴에만 유용합니다.

이 경우 속도는 중요하지 않습니다 (그렇지 않으면이 일반 쿼리 기능을 사용하지 않을 것입니다). 그러나 단순성을 유지하면서 가능한 빨리 실행하고 싶습니다.

위의 옵션 중 어떤 옵션을 선택해야합니까?


편집하다: 나는 간단한 벤치 마크를 실행하십시오 그리고 여전히 어떤 방법이 더 잘 작동하는지 결정할 수 없습니다.

다음은 결과입니다 10,000 번의 시도 (총 시간, 몇 초) :

Array
(
    [match] => Array
        (
            [stripos] => 0.0965
            [preg_match] => 0.2445
            [preg_match?] => 0.1227
            [preg_match?S] => 0.0863
        )

    [no-match] => Array
        (
            [stripos] => 0.1165
            [preg_match] => 0.0812
            [preg_match?] => 0.0809
            [preg_match?S] => 0.0829
        )
)

100,000 번의 시도:

Array
(
    [match] => Array
        (
            [stripos] => 1.2049
            [preg_match] => 1.5079
            [preg_match?] => 1.5564
            [preg_match?S] => 1.5857
        )

    [no-match] => Array
        (
            [stripos] => 1.4833
            [preg_match] => 0.8853
            [preg_match?] => 0.8645
            [preg_match?S] => 0.8986
        )
)

1,000,000 시도:

Array
(
    [match] => Array
        (
            [stripos] => 9.4555
            [preg_match] => 8.7634
            [preg_match?] => 9.0834
            [preg_match?S] => 9.1629
        )

    [no-match] => Array
        (
            [stripos] => 13.4344
            [preg_match] => 9.6041
            [preg_match?] => 10.5849
            [preg_match?S] => 8.8814
        )
)

10,000,000 시도:

Array
(
    [match] => Array
        (
            [stripos] => 86.3218
            [preg_match] => 93.6755
            [preg_match?] => 92.0910
            [preg_match?S] => 105.4128
        )

    [no-match] => Array
        (
            [stripos] => 150.9792
            [preg_match] => 111.2088
            [preg_match?] => 100.7903
            [preg_match?S] => 88.1984
        )
)

결과가 크게 다르다는 것을 알 수 있듯이 이것이 벤치 마크를 수행하는 올바른 방법인지 궁금합니다.

도움이 되었습니까?

해결책 2

나는 더 빠른 것처럼 보이기 때문에 다음과 같은 regexes와 함께 갔다.

  1. if (preg_match('~^(?:INSERT|REPLACE)~i', $query) === 1)
  2. else if (preg_match('~^(?:UPDATE|DELETE)~i', $query) === 1)
  3. else if (preg_match('~^(?:SELECT|EXPLAIN)~i', $query) === 1)

다른 팁

아마 그 중 어느 것도 사용하지 않을 것입니다. 벤치마킹 없이는 확신 할 수 없지만 substr() 보다 빠른 옵션이 될 것입니다 stripos, 전체 문자열을 스캔하지 않기 때문에. 가정합니다 UPDATE 그리고 DELETE 항상 쿼리가 시작될 때 항상 발생하고 더 나은 것은 정확히 6 자 길이 가므로 단일로 할 수 있습니다. substr():

$queryPrefix = strtoupper(substr($query,0,6));
if ($queryPrefix == 'UPDATE' || $queryPrefix == 'DELETE') {

필요한 경우 추가 할 수 있습니다 trim() 접두사가있는 공백을 위해서는 거기에 있지만 아마도 필요하지 않을 것입니다.

업데이트 및 삭제로 중첩 또는 하위 쿼리를하고 있다면 위의 방법이 작동하지 않을 것이며 stripos() 노선. 정상적인 문자열 함수를 선호하는 정규식을 피할 수 있다면 더 빠르고 덜 복잡합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top