السلام عليكم ورحمة الله
الدالة ROW_COUNT
تعيد عدد الصفوف المتأثرة من جملة الاستعلام او الحذف او التعديل بمعنى العملية التي تم تنفيدها
مثال اخر
المؤشرات Explicit Cursors
أصبح من الممكن الآن الإعلان عن مؤشرات متعددة واستخدامها في PSQL. تتوفر المؤشرات الصريحة في بنية DSQL EXECUTE BLOCK وكذلك في الإجراءات والمشغلات المخزنة.
مثال اخر
بالامكان الان اسناد القيم الافتراضية في الاجراءات المخزنة
Defaults for Stored Procedure Arguments
بالامكان استخدام العبارة LEAVE لانهاء حلقة تكرارية او الخروج من تنفيد اي عملية قائمة
العبارة ROW_NUMBER
تعطي رقم متسلسل للصفوف وتعمل مع عبارة Over التجميعية بما ياتي معها من صيغ مختلفة حسب الطلب
العبارة RANK
مثل السابقة ولكن تكرر الترقيم بحال كان مكرر لاحظ النتيجة
العبارة PERCENT_RANK
نفس السابقة وبنسب مئوية
العبارة cume_dist
وايضا بحال كنت تتعامل مع بيانات من مليون وفوق انصح بهذه الصفحة التي تحدد فيها اصدار فايربيرد وحجم الرام وعدد المستخدمين وما الى ذلك فتولد لك ملفين احدهما
firebird.conf وايضا databases.conf لان فايربيرد عند التثبيت يتم تثبيته باعدادت افتراضية تكون سيئة وغير مضبوطة لتناسب حجم العمل الذي تعمل عليه
سوف تقوم الصفحة باعطاء قيم لاستخدام الرامات وقيم لحجم الصفحات لقاعدة البيانات وامور مهمة لذلك
هذه النصائح مجالات مختلفة، من تحسينات الأجهزة/نظام التشغيل وتهيئة Firebird إلى توصيات تحسين SQL.
أولاً: تحسينات الأجهزة/نظام التشغيل:
والصفحة السابقة تقوم باعطاء اغلب الاعدادات المذكورة لتحسين اداء محرك فايربيرد
وعلى سبيل المثال اعدادات خاصة قدمها بحسب مواصفات معينة تتماشى مع المواصفات التي تم تقديمها فقام بالغاء اشياء وفعل اشياء وزاد او غير في اشياء
ومن تجربتي الخاصة استعلامات كانت تاخذ حوالي 350 ملي ثانية على مليون و500 الف سجل اصبحت تأخذ 128 ملي ثانية
بمعنى ان الاعدادات هذه لا تصلح لاي جهاز بالضرورة
اعدادات لملف ملف firebird.conf
اعدادات ملف databases.conf
كما تجدر الاشارة الى ان الاعدادات التي يتم تقديمها تقوم بتحسين اداء فايربيرد ولكن ليس بالضرورة ان يكون افضل ما يكون ولتحصل على افضل شئ تحتاج الى فهم عمل كل هذه الخيارات وتجرب بنفسك
وهناك اشياء اخرى جديدة واشياء قديمة ومهمة و الذي سوف اضيفه كلما سنحت الفرصة لذلك
العبارة MERGE لدمج من مصدر الى جهة مستهدفة
مثال على الاستخدام
كيفية الحصول على عدد السجلات لأي استعلام دون تنفيذه؟
عبارة current_connection تحفظ الاتصال الحالي
ويمكن اجراء عملية ما بها
للحصول على التاريخ الان والساعة
العبارة current_role للحصول على صلاحيات المستخدم الحالي
للحصول على معرف العملية الحالية
للحصول على اسم المستخدم الحالي
تستخدم في القوادح لمعرفة اذا كان هناك حدث حذف حصل
او اضافة او تعديل
ماذا لو لم تكن تريد استخدام مولدات الارقام لاستخدامه مع المفاتيح الاساسية بالجداول
هناك طريقة يمكن فعل ذلك بها باستخدام القوادح .
فعند استخدام مولدات الارقام وكان اخر رقم عندك هو مثلا 23000 وقمت بفتح سجل جديد ثم الغيت العملية وعدت واضفت سجل جديد فسيكون الرقم 23002 وليس 23001
ويجب وقتها التدخل برمجيا واعادة الترقيم الى الخلف بمقدر 1
او استخدام القوادح لاجراء الترقيم كما بالمثال التالي
حيث Doc اسم الجدول ويتم وضع هذه السطور في الحدث قبل الاضافة
ولكن لا ينصح بها اذا كانت بياناتك اكبر من مليون ولازالت تنمو لان جملة Max على البيانات الكثيرة فيها بطئ
بخصول حجم الصفحة في اعدادت ملف قاعدة البيانات دور مهم في اداء قاعدة البيانات
![[صورة: dmiles841.gif]](https://www.ibexpert.net/ibe/uploads/Doc/dmiles841.gif)
![[صورة: dmiles842.gif]](https://www.ibexpert.net/ibe/uploads/Doc/dmiles842.gif)
عند انشاء قاعدة بيانات جديدة افتراضيا يتم وضعه على 16384 وعند انشاء قاعدة البيانات لا يمكن تغييره بعدها الا بانشاء نسخ احتياطي وعملية استرجاع
العديد من العمليات المستندة إلى الفهرس (تعمل الفهارس بشكل أسرع إذا تم تقليل عمق الفهرس)
الدالة ROW_COUNT
كود :
BEGIN
SELECT COL FROM TAB INTO :VAR;
IF (ROW_COUNT = 0) THEN
EXCEPTION NO_DATA_FOUND;
END
تعيد عدد الصفوف المتأثرة من جملة الاستعلام او الحذف او التعديل بمعنى العملية التي تم تنفيدها
مثال اخر
كود :
update Figures set Number = 0 where id = :id;
if (row_count = 0) then
insert into Figures (id, Number) values (:id, 0);
المؤشرات Explicit Cursors
أصبح من الممكن الآن الإعلان عن مؤشرات متعددة واستخدامها في PSQL. تتوفر المؤشرات الصريحة في بنية DSQL EXECUTE BLOCK وكذلك في الإجراءات والمشغلات المخزنة.
كود :
DECLARE RNAME CHAR(31);
DECLARE C CURSOR FOR ( SELECT RDB$RELATION_NAME
FROM RDB$RELATIONS );
BEGIN
OPEN C;
WHILE (1 = 1) DO
BEGIN
FETCH C INTO :RNAME;
IF (ROW_COUNT = 0) THEN
LEAVE;
SUSPEND;
END
CLOSE C;
END
مثال اخر
كود :
DECLARE RNAME CHAR(31);
DECLARE FNAME CHAR(31);
DECLARE C CURSOR FOR ( SELECT RDB$FIELD_NAME
FROM RDB$RELATION_FIELDS
WHERE RDB$RELATION_NAME = :RNAME
ORDER BY RDB$FIELD_POSITION );
BEGIN
FOR
SELECT RDB$RELATION_NAME
FROM RDB$RELATIONS
INTO :RNAME
DO
BEGIN
OPEN C;
FETCH C INTO :FNAME;
CLOSE C;
SUSPEND;
END
END
بالامكان الان اسناد القيم الافتراضية في الاجراءات المخزنة
Defaults for Stored Procedure Arguments
كود :
CREATE PROCEDURE P1 (X INTEGER = 123)
RETURNS (Y INTEGER)
AS
BEGIN
Y = X;
SUSPEND;
END
بالامكان استخدام العبارة LEAVE لانهاء حلقة تكرارية او الخروج من تنفيد اي عملية قائمة
كود :
FOR
SELECT COALESCE(RDB$SYSTEM_FLAG, 0), RDB$RELATION_NAME
FROM RDB$RELATIONS
ORDER BY 1
INTO :RTYPE, :RNAME
DO
BEGIN
IF (RTYPE = 0) THEN
SUSPEND;
ELSE
LEAVE; -- exits current loop
END
كود :
CNT = 100;
L1:
WHILE (CNT >= 0) DO
BEGIN
IF (CNT < 50) THEN
LEAVE L1; -- exists WHILE loop
CNT = CNT - l;
END
العبارة ROW_NUMBER
كود :
select
id,
salary,
row_number() over (order by salary)
from employee
order by salary;
تعطي رقم متسلسل للصفوف وتعمل مع عبارة Over التجميعية بما ياتي معها من صيغ مختلفة حسب الطلب
العبارة RANK
كود :
select
id,
salary,
rank() over (order by salary)
from employee
order by salary;
مثل السابقة ولكن تكرر الترقيم بحال كان مكرر لاحظ النتيجة
كود :
rank salary id
-- ------ ----
3 8.00 1
4 9.00 2
1 10.00 3
5 10.00 3
2 12.00 5
العبارة PERCENT_RANK
كود :
select
id,
salary,
rank() over (order by salary),
percent_rank() over (order by salary)
from employee
order by salary;
نفس السابقة وبنسب مئوية
العبارة cume_dist
كود :
select
id,
salary,
cume_dist() over (order by salary)
from employee
order by salary;
كود :
cume_dist salary id
-- ------ ---------
3 8.00 0.2
4 9.00 0.4
1 10.00 0.8
5 10.00 0.8
2 12.00 1
وايضا بحال كنت تتعامل مع بيانات من مليون وفوق انصح بهذه الصفحة التي تحدد فيها اصدار فايربيرد وحجم الرام وعدد المستخدمين وما الى ذلك فتولد لك ملفين احدهما
firebird.conf وايضا databases.conf لان فايربيرد عند التثبيت يتم تثبيته باعدادت افتراضية تكون سيئة وغير مضبوطة لتناسب حجم العمل الذي تعمل عليه
كود :
https://cc.ib-aid.com/democalc.html
سوف تقوم الصفحة باعطاء قيم لاستخدام الرامات وقيم لحجم الصفحات لقاعدة البيانات وامور مهمة لذلك
هذه النصائح مجالات مختلفة، من تحسينات الأجهزة/نظام التشغيل وتهيئة Firebird إلى توصيات تحسين SQL.
أولاً: تحسينات الأجهزة/نظام التشغيل:
- استخدام SSD لقاعدة البيانات: نقل قاعدة البيانات إلى SSD سيُحسّن سرعة القراءة والكتابة بشكل كبير.
- استخدام RAID 10: إذا كنت تستخدم RAID 1 أو RAID 5، ففكر في استخدام RAID 10، فهو أسرع بنسبة 15-25%.
- التحقق من BBU: تأكد من أن بطارية BBU (بطارية احتياطية للذاكرة) في حالة جيدة.
- ضبط ذاكرة التخزين المؤقت للكتابة على "write-back": سيُحسّن هذا الأداء عند كتابة البيانات على القرص.
- تمكين ذاكرة التخزين المؤقت للقراءة: سيُحسّن هذا الأداء عند قراءة البيانات من القرص.
- التحقق من نظام القرص الفرعي: تأكد من أن نظام القرص الفرعي يعمل بشكل صحيح.
- استخدام مساحة مؤقتة سريعة: خصص مساحة مؤقتة سريعة (SSD أو محرك RAM) لعمليات الفرز الكبيرة.
- استخدام SuperClassic أو Classic في Firebird 2.5: يُقدم SuperClassic أداءً أفضل للعمليات المتزامنة، بينما يُقدم Classic أداءً أفضل للعمليات المتسلسلة.
- استخدام SuperServer 3.0 في Firebird 3: يُقدم SuperServer 3.0 أداءً أفضل للعمليات المتزامنة والمتسلسلة.
- ضبط عدد صفحات ذاكرة التخزين المؤقت: اضبط عدد صفحات ذاكرة التخزين المؤقت وفقًا لحجم قاعدة البيانات وحجمها.
- ضبط عدد الموصلات: اضبط عدد الموصلات وفقًا لعدد المستخدمين المتزامنين.
- ضبط حجم ذاكرة التخزين المؤقت للقراءة/الكتابة: اضبط حجم ذاكرة التخزين المؤقت للقراءة/الكتابة وفقًا لحجم قاعدة البيانات وحجمها.
- ضبط مسار الملف المؤقت: خصص مسارًا سريعًا للملفات المؤقتة.
- إلغاء تنشيط الميزات غير المستخدمة: قم بإلغاء تنشيط الميزات غير المستخدمة لتحسين الأداء.
والصفحة السابقة تقوم باعطاء اغلب الاعدادات المذكورة لتحسين اداء محرك فايربيرد
وعلى سبيل المثال اعدادات خاصة قدمها بحسب مواصفات معينة تتماشى مع المواصفات التي تم تقديمها فقام بالغاء اشياء وفعل اشياء وزاد او غير في اشياء
ومن تجربتي الخاصة استعلامات كانت تاخذ حوالي 350 ملي ثانية على مليون و500 الف سجل اصبحت تأخذ 128 ملي ثانية
بمعنى ان الاعدادات هذه لا تصلح لاي جهاز بالضرورة
اعدادات لملف ملف firebird.conf
كود :
ServerMode = Super
DefaultDbCachePages = 50K # pages (SuperServer) - increase pages in databases.conf, not here
LockMemSize = 20M # bytes (SuperServer)
LockHashSlots = 40099 # slots
MaxUnflushedWrites = -1 # default for posix (non-Windows)
MaxUnflushedWriteTime = -1 # default for posix (non-Windows)
UseFileSystemCache = true
TempCacheLimit = 256M
RemoteServicePort = 3050
InlineSortThreshold = 16384 # use REFETCH plan for big sortings
ExtConnPoolSize = 64 # external connections pool size
ExtConnPoolLifeTime = 3600 # seconds
#set DataTypeCompatibility according Migration Guide https://ib-aid.com/download /docs/fb4migrationguide.html
#DataTypeCompatibility =
#WireCryptPlugin = ChaCha64, ChaCha, Arc4
#WireCrypt = Enabled (for client) / Required (for server)
#WireCompression = false
#RemoteAuxPort = 0
#authentication plugin setup
#Recommendation - use SELECT * FROM SEC$USERS
#to check that you have users for all plugins
AuthServer = Srp256, Legacy_Auth
UserManager = Srp, Legacy_UserManager
#MaxIdentifierByteLength = 252
#MaxIdentifierCharLength = 63
#DefaultTimeZone =
#SnapshotsMemSize = 64K # bytes
#TipCacheBlockSize = 4M # bytes
اعدادات ملف databases.conf
كود :
security.db = $(dir_secDb)/security4.fdb
{
RemoteAccess = false
DefaultDbCachePages = 256
}
testdb = c:\temp\mydb1.fdb
{
DefaultDBCachePages = 115536
LockMemSize = 30M
TempCacheLimit =2185M
}
كما تجدر الاشارة الى ان الاعدادات التي يتم تقديمها تقوم بتحسين اداء فايربيرد ولكن ليس بالضرورة ان يكون افضل ما يكون ولتحصل على افضل شئ تحتاج الى فهم عمل كل هذه الخيارات وتجرب بنفسك
وهناك اشياء اخرى جديدة واشياء قديمة ومهمة و الذي سوف اضيفه كلما سنحت الفرصة لذلك
العبارة MERGE لدمج من مصدر الى جهة مستهدفة
مثال على الاستخدام
كود :
MERGE INTO books b
USING purchases p
ON p.title = b.title and p.type = 'bk'
WHEN MATCHED THEN
UPDATE SET b.desc = b.desc || '; ' || p.desc
WHEN NOT MATCHED THEN
INSERT (title, desc, bought) values (p.title, p.desc, p.bought);
كود :
MERGE INTO customers c
USING (SELECT * from customers_delta WHERE id > 10) cd
ON (c.id = cd.id)
WHEN MATCHED THEN
UPDATE SET name = cd.name
WHEN NOT MATCHED THEN
INSERT (id, name) values (cd.id, cd.name);
كود :
MERGE INTO numbers
USING (
WITH RECURSIVE r(n) AS (
SELECT 1 FROM rdb$database
UNION ALL
SELECT n+1 FROM r WHERE n < 200
)
SELECT n FROM r
) t
ON numbers.num = t.n
WHEN NOT MATCHED THEN
INSERT(num) VALUES(t.n);
كيفية الحصول على عدد السجلات لأي استعلام دون تنفيذه؟
كود :
SELECT COUNT(*) FROM ( select * from employee where emp_no > 8 );
عبارة current_connection تحفظ الاتصال الحالي
كود :
select current_connection from rdb$database
ويمكن اجراء عملية ما بها
كود :
execute procedure P_Login(current_connection)
للحصول على التاريخ الان والساعة
كود :
select current_date from rdb$database
كود :
select current_time(2) from rdb$database
كود :
select current_time from rdb$database
العبارة current_role للحصول على صلاحيات المستخدم الحالي
كود :
if (current_role <> 'MANAGER')
then exception only_managers_may_delete;
else
delete from Customers where custno = :custno;
للحصول على معرف العملية الحالية
كود :
select current_transaction from rdb$database
كود :
New.Txn_ID = current_transaction;
للحصول على اسم المستخدم الحالي
كود :
create trigger bi_customers for customers before insert as
begin
New.added_by = CURRENT_USER;
New.purchases = 0;
end
كود :
create trigger bi_customers for customers before insert as
begin
New.added_by = USER;
New.purchases = 0;
end
تستخدم في القوادح لمعرفة اذا كان هناك حدث حذف حصل
كود :
if (deleting) then
begin
insert into Removed_Cars (id, make, model, removed)
values (old.id, old.make, old.model, current_timestamp);
end
او اضافة او تعديل
كود :
if (inserting or updating) then
begin
if (new.serial_num is null) then
new.serial_num = gen_id(gen_serials, 1);
end
ماذا لو لم تكن تريد استخدام مولدات الارقام لاستخدامه مع المفاتيح الاساسية بالجداول
هناك طريقة يمكن فعل ذلك بها باستخدام القوادح .
فعند استخدام مولدات الارقام وكان اخر رقم عندك هو مثلا 23000 وقمت بفتح سجل جديد ثم الغيت العملية وعدت واضفت سجل جديد فسيكون الرقم 23002 وليس 23001
ويجب وقتها التدخل برمجيا واعادة الترقيم الى الخلف بمقدر 1
او استخدام القوادح لاجراء الترقيم كما بالمثال التالي
كود :
if(Coalesce(new.id,0)=0) then
new.id = Coalesce((Select max(id) from doc),0)+1;
begin
حيث Doc اسم الجدول ويتم وضع هذه السطور في الحدث قبل الاضافة
ولكن لا ينصح بها اذا كانت بياناتك اكبر من مليون ولازالت تنمو لان جملة Max على البيانات الكثيرة فيها بطئ
بخصول حجم الصفحة في اعدادت ملف قاعدة البيانات دور مهم في اداء قاعدة البيانات
![[صورة: dmiles841.gif]](https://www.ibexpert.net/ibe/uploads/Doc/dmiles841.gif)
![[صورة: dmiles842.gif]](https://www.ibexpert.net/ibe/uploads/Doc/dmiles842.gif)
عند انشاء قاعدة بيانات جديدة افتراضيا يتم وضعه على 16384 وعند انشاء قاعدة البيانات لا يمكن تغييره بعدها الا بانشاء نسخ احتياطي وعملية استرجاع
العديد من العمليات المستندة إلى الفهرس (تعمل الفهارس بشكل أسرع إذا تم تقليل عمق الفهرس)
- السجلات العريضة: مع وجود هياكل بيانات عريضة جدًا، أي مع العديد من الأعمدة الطويلة جدًا، يكون قراءة مجموعة البيانات أكثر فعالية. بالنسبة لمجموعات البيانات التي لا تلائم صفحة واحدة، يلزم قراءة عدة صفحات لاسترداد مجموعة بيانات واحدة. وينطبق الأمر نفسه على الكتابة، أي أن الجلب عبر عدة صفحات ضروري.
- حقول blob الكبيرة: يتم تخزين البيانات واسترجاعها بكفاءة أكبر إذا كان عدد الصفحات التي تحتاج إلى جلبها أقل. مع البيانات blob الأكبر، تكون عمليات الكتابة والقراءة أكثر فعالية أيضًا، حيث يلزم على سبيل المثال 100 عملية وصول لعمود blob بحجم 100 كيلو بايت مع حجم صفحة 1 كيلو بايت. ولكن مع حجم صفحة 8 كيلو بايت، يلزم فقط 13 عملية.
- حجم صفحة صغير: يكون حجم صفحة صغير كافياً إذا كان العديد من المعاملات يعيد فقط عددًا قليلاً من الأسطر. يمكن الوصول إلى هياكل الجداول النحيل مع صفحات قاعدة بيانات صغيرة بشكل أسرع للقراءة والكتابة حيث يلزم ذاكرة أقل، ويمكن الاحتفاظ بالمزيد من صفحات قاعدة البيانات في ذاكرة التخزين المؤقت. ومع ذلك، لا يُنصح باستخدام قاعدة بيانات بحجم صفحة أقل من 4096 على Windows، حيث أن هذا هو حجم كتلة Windows. لذلك، لا تقدم أحجام الصفحات الأصغر أي ميزات، حيث سيظل Windows يستخرج كتل 4 كيلو بايت.
- يؤثر حجم صفحة قاعدة البيانات بشكل مباشر على مقدار ذاكرة التخزين المؤقت لقاعدة البيانات، والذي يؤثر على جميع النقاط المذكورة أعلاه. إذا تم تحديد حجم صفحة 16 كيلو بايت وحدد ذاكرة التخزين المؤقت لقاعدة بيانات خادم Firebird في firebird.conf بحد أقصى 128,000 صفحة، فسيتم توفير إجمالي ذاكرة تخزين مؤقت 2 غيغابايت لإيواء صفحات البيانات. لا يوفر نفس مواصفات ذاكرة التخزين المؤقت مع حجم صفحة 1 كيلو بايت سوى 180 ميغابايت من ذاكرة التخزين المؤقت. يُرجى الرجوع إلى تكوين الذاكرة للحصول على تفاصيل مواصفات ذاكرة التخزين المؤقت لخادم Firebird Superserver وخادم Classic.
- على الرغم من إمكانية إضاعة مساحة معينة بحجم صفحة كبير، إلا أنه لا ينبغي أن يكون هذا مشكلة خطيرة بأسعار الأجهزة الحالية، ويمكن أن يوفر مزايا أكبر في الأداء.
- الطريقة الوحيدة لتغيير حجم صفحة قاعدة البيانات لاحقًا هي إجراء نسخة احتياطية لقاعدة البيانات يليها استعادة (بند قائمة IBExpert، الخدمات / استعادة قاعدة البيانات) حيث يمكن إعادة تعريف حجم صفحة قاعدة البيانات.
قل: اللهم فاطِرَ السماوات والأرض عالم الغيبِ والشهادة، ربَّ كُلِّ شَيءٍ ومَلِيكَه، أَشْهد أن لا إله إلا أنت، أعوذ بك من شرِّ نفسي وشرِّ الشيطان وشِرْكِهِ وأن أقترف على نفسي سوءًا أو أجرُّه إلى مسلم