سؤال

هل هناك أي اختلاف في الكفاءة في الصلة الداخلية الصريحة والضمنية؟على سبيل المثال:

SELECT * FROM
table a INNER JOIN table b
ON a.id = b.id;

ضد.

SELECT a.*, b.*
FROM table a, table b
WHERE a.id = b.id;
هل كانت مفيدة؟

المحلول

من ناحية الأداء، فهي متماثلة تمامًا (على الأقل في SQL Server).

ملاحظة:كن على علم بأن IMPLICIT OUTER JOIN تم إهمال بناء الجملة منذ SQL Server 2005.(ال IMPLICIT INNER JOIN لا يزال بناء الجملة كما هو مستخدم في السؤال مدعومًا)

إهمال صيغة الانضمام "النمط القديم":شيء جزئي فقط

نصائح أخرى

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

في MySQL 5.1.51، كلا الاستعلامين لهما خطط تنفيذ متطابقة:

mysql> explain select * from table1 a inner join table2 b on a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.02 sec)

mysql> explain select * from table1 a, table2 b where a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.00 sec)

table1 يحتوي على 166208 صفًا؛ table2 لديه حوالي 1000 الصفوف.

هذه حالة بسيطة جدًا؛لا يثبت بأي حال من الأحوال أن مُحسِّن الاستعلام لن يرتبك وينشئ خططًا مختلفة في حالة أكثر تعقيدًا.

يحتوي بناء الجملة الثاني على إمكانية غير مرغوب فيها للصلة المتقاطعة:يمكنك إضافة جداول إلى الجزء FROM بدون عبارة WHERE المقابلة.وهذا يعتبر ضارا.

تستخدم الإجابة الأولى التي قدمتها ما يعرف بصيغة الانضمام ANSI، أما الإجابة الأخرى فهي صالحة وستعمل في أي قاعدة بيانات علائقية.

أتفق مع جروم على أنه يجب عليك استخدام بناء جملة الانضمام إلى ANSI.وكما قالوا، السبب الرئيسي هو الوضوح.بدلاً من وجود عبارة حيث تحتوي على الكثير من المسندات، بعضها يربط الجداول والبعض الآخر يقيد الصفوف التي تم إرجاعها باستخدام بناء جملة ربط ANSI، فإنك توضح بشكل واضح الشروط التي يتم استخدامها لربط الجداول الخاصة بك والتي يتم استخدامها لتقييد نتائج.

@لوماكس:فقط للتوضيح، أنا متأكد تمامًا من أن كلا من بناء الجملة أعلاه مدعومان بواسطة SQL Serv 2005.ومع ذلك، فإن بناء الجملة أدناه غير مدعوم

select a.*, b.*  
from table a, table b  
where a.id *= b.id;

وبوجه خاص، الصلة الخارجية (*=) غير معتمدة.

من ناحية الأداء، فهي متماثلة تمامًا (على الأقل في SQL Server) ولكن انتبه إلى أنها تتجاهل بناء جملة الانضمام هذا وأنها غير مدعومة بواسطة SQL Server2005 خارج الصندوق.

أعتقد أنك تفكر في عاملي التشغيل *= و=* المهملين مقابل عاملي التشغيل."الانضمام الخارجي".

لقد قمت الآن باختبار التنسيقين المقدمين، وهما يعملان بشكل صحيح على قاعدة بيانات SQL Server 2008.وفي حالتي، فقد أسفروا عن خطط تنفيذ متطابقة، لكنني لم أستطع أن أقول بثقة أن هذا سيكون صحيحًا دائمًا.

في بعض قواعد البيانات (خاصة Oracle) يمكن أن يحدث ترتيب الصلات فرقًا كبيرًا في أداء الاستعلام (إذا كان هناك أكثر من جدولين).في أحد التطبيقات، كان لدينا حرفيًا اختلافان في الحجم في بعض الحالات.يمنحك استخدام بناء جملة الصلة الداخلية التحكم في هذا - إذا كنت تستخدم بناء جملة التلميحات الصحيحة.

لم تحدد قاعدة البيانات التي تستخدمها، ولكن الاحتمالية تشير إلى وجود SQL Server أو MySQL حيث لا يوجد فرق حقيقي.

كما ذكر Leigh Caldwell، يمكن لمُحسِّن الاستعلامات إنتاج خطط استعلام مختلفة بناءً على ما يبدو وظيفيًا مثل نفس عبارة SQL.لمزيد من القراءة حول هذا الأمر، قم بإلقاء نظرة على منشورات المدونة التالية: -

مشاركة واحدة من فريق Oracle Optimizer

منشور آخر من مدونة "البيانات المنظمة".

أتمنى أن تجد هذا مثيرا للاهتمام.

الأداء الحكيم، لا ينبغي أن يحدث أي فرق.يبدو أن بناء جملة الصلة الصريحة أكثر نظافة بالنسبة لي لأنه يحدد بوضوح العلاقات بين الجداول في جملة from ولا يؤدي إلى فوضى في جملة Where.

من خلال تجربتي، غالبًا ما ينتج عن استخدام صيغة جملة cross join-with-a-where-clause خطة تنفيذ تالفة في الدماغ، خاصة إذا كنت تستخدم منتج Microsoft SQL.على سبيل المثال، الطريقة التي يحاول بها SQL Server تقدير عدد صفوف الجدول، هي طريقة فظيعة للغاية.يمنحك استخدام بناء جملة الصلة الداخلية بعض التحكم في كيفية تنفيذ الاستعلام.لذلك من وجهة نظر عملية، نظرًا للطبيعة الرجعية لتقنية قاعدة البيانات الحالية، عليك أن تتعامل مع الصلة الداخلية.

في الأساس، الفرق بين الاثنين هو أن أحدهما مكتوب بالطريقة القديمة، والآخر مكتوب بالطريقة الحديثة.أنا شخصياً أفضّل النص الحديث الذي يستخدم التعريفات الداخلية واليسرى والخارجية واليمنى لأنها أكثر تفسيرية وتجعل الكود أكثر قابلية للقراءة.

عند التعامل مع الصلات الداخلية، لا يوجد فرق حقيقي في سهولة القراءة أيضًا، ومع ذلك، قد يصبح الأمر معقدًا عند التعامل مع الصلات اليسرى واليمنى كما هو الحال في الطريقة القديمة، ستحصل على شيء مثل هذا:

SELECT * 
FROM table a, table b
WHERE a.id = b.id (+);

ما ورد أعلاه هو الطريقة القديمة لكيفية كتابة الصلة اليسرى بدلاً من ما يلي:

SELECT * 
FROM table a 
LEFT JOIN table b ON a.id = b.id;

كما ترون بصريًا، فإن الطريقة الحديثة لكيفية كتابة البرنامج النصي تجعل الاستعلام أكثر قابلية للقراءة.(بالمناسبة، الأمر نفسه ينطبق على الصلات الصحيحة وأكثر تعقيدًا قليلاً بالنسبة للصلات الخارجية).

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top