ذاكرة التخزين المؤقت للاستعلام MySQL ، استعلام SQL المعقدة

StackOverflow https://stackoverflow.com/questions/4400271

  •  25-09-2019
  •  | 
  •  

سؤال

فيما يلي المشكلة تمنحني صداعًا.

لقد قمت بإعداد خادم MySQL لاستخدام "Query Chaching".

set global query_cache_size = 10000000;

يبدو أن ذاكرة التخزين المؤقت الخاصة بي تعمل لأن إخراج

SHOW STATUS LIKE 'Qcache%';  

كالتالي

+-------------------------+----------+    
|    Variable_name        | Value    |           
+-------------------------+----------+     
| Qcache_free_blocks      | 1        |
| Qcache_free_memory      | 47223976 |
| Qcache_hits             | 6709     |                                       
| Qcache_inserts          | 2314     |                                    
| Qcache_lowmem_prunes    | 0        |                                  
| Qcache_not_cached       | 365      |                                  
| Qcache_queries_in_cache | 441      |                                   
| Qcache_total_blocks     | 960      |                                     
+-------------------------+----------+ 

ولكن ، لا يتم تخزين المؤقتة مؤقتًا فيما يلي (الاستعلام المعقد ، مع الاختيار الداخلي وما إلى ذلك).

يأخذ alsways ما لا يقل عن 0.8 ثانية لاسترداد البيانات لهذا الاستعلام. كيف يمكنني إحضار mysql إلى تخزين نتائج هذا الاستعلام في ذاكرة التخزين المؤقت?

حاولت OT إزالة الاختيار الداخلي ولكن هذا لم يجعل اختلافًا.

SELECT p.id
   AS
   project_id,
   p.code
   AS project_code,
   p.title
   AS project_title,
   p.start_date
   AS project_start_date,
   p.end_date
   AS project_end_date,
   p.modf
   AS project_modf,
   ( p.budget * (SELECT 1 / r.VALUE
                 FROM   exchange_rates r
                 WHERE  r.class_currency_id = p.class_budget_currency_id) )
   AS
   project_budget,
   (SELECT z.txt
    FROM   sys_labels z
    WHERE  z.id = ps.value_label_id
           AND z.lng = 'en')
   AS project_status,
   (SELECT z.txt
    FROM   sys_labels z
    WHERE  z.id = ps.data_label_id
           AND z.lng = 'en')
   AS project_color,
   GROUP_CONCAT(DISTINCT pt.class_topic_id)
   AS projects_thematic_area_ids,
   u.id
   AS project_owner_id
FROM   projects AS p
   LEFT JOIN projects_thematic_areas AS pt
     ON pt.project_id = p.id
   LEFT JOIN sys_users AS u
     ON u.id = p.owner_uid
   LEFT JOIN class_data s
     ON s.id = p.class_status_id
   LEFT JOIN class_data AS ps
     ON ps.id = s.id
   LEFT JOIN sys_labels AS prdz1
     ON prdz1.id = prd.value_label_id
        AND prdz1.lng = 'en'
   LEFT JOIN sys_labels AS prdz2
     ON prdz2.id = prd.data_label_id
        AND prdz2.lng = 'en'
   LEFT JOIN projects_locations AS pl
     ON pl.project_id = p.id
   LEFT JOIN class_data AS l
     ON l.id = pl.class_location_id
   LEFT JOIN class_data AS r
     ON r._lft <= l._lft
        AND r._rgt >= l._rgt
        AND r._level = 1
        AND r.class_id = 5
   LEFT JOIN class_data AS c
     ON c._lft <= l._lft
        AND c._rgt >= l._rgt
        AND c._level = 2
        AND c.class_id = 10
   LEFT JOIN projects_donors AS pd
     ON pd.project_id = p.id
   LEFT JOIN institutions AS i
     ON pd.inst_id = i.id
   LEFT JOIN class_data AS ic
     ON ic.id = i.class_country_id
   LEFT JOIN projects_deliverables AS d
     ON d.project_id = p.id
WHERE  1 = 1
   AND p.is_del = "f"
   AND p.is_active = "t"
GROUP  BY p.id
ORDER  BY p.modf DESC,
      p.code DESC 

أي مساعدة مدرس ....

يعتبر

ج.

هل كانت مفيدة؟

المحلول

بالإضافة إلى الإجابات السابقة: لن يتم استخدام ذاكرة التخزين المؤقت للاستعلام حتى لو كان الاستعلام موجودًا إذا كانت هناك تغييرات في أي من الجداول المحددة.

ولكن لماذا تنضم إلى هذه الجداول عندما لا تختار أي شيء منها؟ كما أنه ربما لا ينبغي عليك تحديد أي شيء إذا كنت تستطيع الانضمام إليه.

شيء من هذا القبيل من شأنه أن يختار نفس الشيء بالضبط:

SELECT
   p.id AS project_id,
   p.code AS project_code,
   p.title AS project_title,
   p.start_date AS project_start_date,
   p.end_date AS project_end_date,
   p.modf AS project_modf,
   p.budget * (1 / r.VALUE) AS project_budget,
   z1.txt AS project_status,
   z2.txt AS project_color,
   GROUP_CONCAT(DISTINCT pt.class_topic_id) AS projects_thematic_area_ids,
   u.id AS project_owner_id
FROM
   projects AS p
   LEFT JOIN projects_thematic_areas AS pt ON pt.project_id = p.id
   LEFT JOIN sys_users AS u ON u.id = p.owner_uid
   LEFT JOIN exchange_rates AS r ON r.class_currency_id = p.class_budget_currency_id
   LEFT JOIN class_data s ON s.id = p.class_status_id
   LEFT JOIN class_data AS ps ON ps.id = s.id
   LEFT JOIN sys_labels AS z1 ON z1.id = ps.value_label_id AND z1.lng = 'en'
   LEFT JOIN sys_labels AS z2 ON z2.id = ps.data_label_id AND z2.lng = 'en'
WHERE
   1
   AND p.is_del = "f"
   AND p.is_active = "t"
GROUP  BY
   p.id
ORDER  BY
   p.modf DESC,
   p.code DESC 

بالطبع لديك فهارس (مجتمعة) على جميع المفاتيح الأجنبية ، حيث الحقول وحقول المجموعة. فكر في استخدام حقل TinyInt أو Enum لقيمك المنطقية. قد ترغب أيضًا في التفكير في عدم اختيار Group_Concat حتى تتمكن من فقدان المجموعة. وربما استخدام Join Inner بدلاً من اليسار إذا كنت متأكدًا من وجود العلاقة.

نصائح أخرى

قد تحاول SELECT SQL_CACHE ... FROM ...

بعض الأشياء الأساسية التي يمكنك تجربتها:

  • إقرأ ال استفسار وثائق ذاكرة التخزين المؤقت للتأكد من أنك تفهم الأساسيات وقم بإعدادها بشكل صحيح.
  • عزل خادم قاعدة بيانات MySQL بشكل مثالي ، بحيث يقوم فقط بتشغيل الأوامر التي تقدمها. إذا لم تتمكن من القيام بذلك ، فحاول إعداد الاختبارات وتشغيلها على جهاز آخر.
  • قم بتشغيل استعلام بسيط وانظر إلى Qcache_hits و Com_select متغيرات الحالة لتحديد ما إذا كان يتم ضرب ذاكرة التخزين المؤقت للاستعلام أم لا.
  • جرب استعلامك المعقد ومراقبة نفس القيم. إذا لم يكن استعلامك يضرب ذاكرة التخزين المؤقت ، فجرّب أجزاء أصغر منه حتى تكتشف ما الذي يتسبب في عدم تخزينه مؤقتًا. إذا تم تخزينه مؤقتًا ، فقد تكون المشكلة ناتجة عن أي من الجداول الموجودة في الاستعلام الذي يتم تحديثه بين الاستعلامات التي من شأنها إبطال النسخة المخزنة مؤقتًا.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top