سؤال

لدي وظيفة Query DB Generic تقوم بتشغيل الشيكات التالية في كل مرة يتم إصدار استعلام SQL:

  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() المكالمة هي الطريقة أسرع من القيام preg_match(), ، ولكن منذ أن أدعو strIpos() مرتين أنا حقا غير متأكد من أي واحد ينبغي أن يؤدي أفضل.

ال S يوفر معدل النمط في الخيار الثاني أيضا بعض الارتباك في رأسي، من الدليل:

عندما يتم استخدام نمط عدة مرات، فإن الأمر يستحق قضاء المزيد من الوقت في تحليله من أجل تسريع الوقت المستغرق للمطابقة. إذا تم تعيين هذا المعدل، فسيتم تنفيذ هذا التحليل الإضافي. في الوقت الحاضر، دراسة نمط مفيد فقط لأنماط غير مرتبطة لا تحتوي على حرف بدء ثابت واحد.

في هذه الحالة، ليست السرعة أمرا بالغ الأهمية (وإلا فلن أستخدم وظيفة الاستعلام العام هذه) ولكن ما زلت ترغب في تشغيلها بأسرع وقت ممكن مع الحفاظ عليها بساطة.

أي من الخيارات أعلاه يجب أن أختار؟


تعديل: لقد قمت تشغيل معيار بسيط وما زلت لا أستطيع تحديد الطريقة التي تعمل بشكل أفضل.

وهنا النتائج ل 10000 محاولة (إجمالي الوقت المستغرق، في ثوان):

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 Tries.:

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