اوراکل 26ai – امکان استفاده از bind variable با قابلیت Materialized View Query Rewrite

تا قبل از نسخه 26ai، کوئری‌هایی که شامل bind variable بودند، نمی‌توانستند از قابلیت query rewrite با استفاده از materialized view (MV) بهره ببرند و اوراکل مجبور بود داده‌ها را مستقیماً از جدول‌های پایه بخواند، که باعث از دست رفتن مزایای کاراییِ داده‌های پیش‌تجمیع‌شده (pre-aggregated data) می‌شد.

از Oracle AI Database 26ai به بعد، این محدودیت حذف شده است و این بهبود به optimizer اجازه می‌دهد مقدار واقعی bind variable را در زمان اجرا بررسی کرده و تصمیم بگیرد که آیا کوئری می‌تواند با استفاده از MV بازنویسی شود یا خیر.

مقایسه رفتار در اوراکل 19c و 26ai

ایجاد Materialized View

SQL> CREATE MATERIALIZED VIEW vahid.mv_emp_dep
ENABLE QUERY REWRITE AS
SELECT department_id,
       COUNT(*) AS emp_count,
       SUM(salary) AS total_salary
FROM vahid.employees where department_id<100
GROUP BY department_id;

Materialized view created

این MV داده‌های تجمیع‌شدهٔ کارمندان را برای دپارتمان‌هایی با شناسهٔ کمتر از ۱۰۰ ذخیره کرده و برای query rewrite خودکار مناسب است.

(بیشتر…)

قابلیت RESETTABLE در اوراکل 26ai

در دیتابیس اوراکل، state بسته‌های PL/SQL در سطح session حفظ می شود. یعنی زمانی که یک package در session ای اجرا می‌شود، متغیرهای global آن، مقادیر خود را در میان چندین فراخوانی حفظ می‌کنند. در نسخه‌های قبلی Oracle(قبل از 26ai)، زمانی که یک package دوباره compile می‌شد، تمام sessionهایی که state آن package را نگه داشته اند با خطاهای ORA-04068 مواجه می‌شدند.

در اوراکل 26ai، عبارت RESETTABLE راهی جدید برای مدیریت state بسته‌های PL/SQL معرفی می‌کند. با استفاده از این عبارت، زمانی که package تشخیص دهد وضعیت آن دیگر معتبر نیست، به‌صورت خودکار reset می‌شود، و مانع از کرش کردن session می شود. برای درک بهتر عملکرد آن، سناریوی عملی زیر را بررسی می‌کنیم. 

(بیشتر…)

اوراکل 26ai – چگونه با عبارت QUALIFY نتایج توابع تحلیلی را بدون subquery فیلتر کنیم؟

فرض کنید میخواهیم از جدول employees، از هر دپارتمان، فقط اطلاعات کارمندی را نمایش دهیم که بالاترین حقوق را دارد. برای گرفتن این خروجی، تا قبل از نسخه 26ai معمولا از subquery استفاده می کردیم:

SELECT *
FROM (
  SELECT employee_id,
         first_name,
         department_id,
         salary,
         RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS Rank_Per_DEP
  FROM employees
)
WHERE Rank_Per_DEP = 1;

(بیشتر…)