الاعتبار الأداء: صفوف الفراد في جداول متعددة مقابل تركيز جميع الصفوف في طاولة واحدة

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

سؤال

دراسة الأداء: صفوف الفراد في جداول متعددة مقابل تركيز جميع الصفوف في جدول واحد.

أهلا.

أحتاج إلى تسجيل معلومات حول كل خطوة تستمر في التطبيق في SQL DB. هناك طاولات معينة، أريد أن يكون السجل مرتبطا بما يلي: المنتج - يجب تسجيل الدخول عند تغيير المنتج تغيير إلخ. ترتيب - نفسه كما فوق الشحن - نفسه إلخ.

سيتم استرجاع البيانات في كثير من الأحيان.

لدي بعض الأفكار حول كيفية القيام بذلك:

  1. لديك جدول سجل سيحتوي على أعمدة لجميع هذه الجداول، ثم عندما أريد أن تمثل البيانات في UI للحصول على منتج معين سيؤدي إلى تحديد * من سجل حيث LogID = Product.productID. أعلم أن هذا قد يكون مضحكا أن يكون لديك العديد من cols، لكن لدي هذا الشعور بأن الأداء سيكون أفضل. في من ناحية أخرى سيكون هناك كمية هائلة من الصفوف في هذا الجدول.
  2. لديك العديد من جداول السجل لكل نوع سجل (Productlogs، Transllogs وما إلى ذلك) أنا لا أحب هذه الفكرة حقا لأنه غير متسق ولديه العديد من الجداول مع نفس الهيكل لا معنى له، ولكن (؟) قد يكون أسرع عند البحث في جدول له كمية أقل من الصفوف (MI خطأ؟).
  3. وفقا لبيان لا. 1، ويمكنني القيام بجدول ثان لشد واحد إلى واحد سيكون لديه cols logid و tablenamid و rowid، وسوف يشير إلى صف السجل إلى العديد من صفوف الجدول في DB، مما سيكون له UDF لاسترداد البيانات (مثل سجل Log 234 ينتمي إلى طاولة العملاء في CustomerID 345 ولجهاز المنتج حيث المنتج = Rowid)؛ أعتقد أن هذه هي أجمل طريقة للقيام بذلك، ولكن مرة أخرى، قد يكون هناك كمية هائلة من الصفوف، هل سيتبطئ البحث؟ أو هذه هي الطريقة التي يجب القيام بها، ماذا يقول؟ ...

مثال على رقم 3 في القائمة الواردة أعلاه:

CREATE TABLE [dbo].[Log](
    [LogId] [int] IDENTITY(1,1) NOT NULL,
    [UserId] [int] NULL,
    [Description] [varchar](1024) NOT NULL,
 CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED 
(
    [LogId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[Log]  WITH CHECK ADD  CONSTRAINT [FK_Log_Table] FOREIGN KEY([UserId])
REFERENCES [dbo].[Table] ([TableId])
GO
ALTER TABLE [dbo].[Log] CHECK CONSTRAINT [FK_Log_Table]
---------------------------------------------------------------------
CREATE TABLE [dbo].[LogReference](
    [LogId] [int] NOT NULL,
    [TableName] [varchar](32) NOT NULL,
    [RowId] [int] NOT NULL,
 CONSTRAINT [PK_LogReference] PRIMARY KEY CLUSTERED 
(
    [LogId] ASC,
    [TableName] ASC,
    [RowId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[LogReference]  WITH CHECK ADD  CONSTRAINT [FK_LogReference_Log] FOREIGN KEY([LogId])
REFERENCES [dbo].[Log] ([LogId])
GO
ALTER TABLE [dbo].[LogReference] CHECK CONSTRAINT [FK_LogReference_Log]
---------------------------------------------------------------------
CREATE FUNCTION GetLog
(   
    @TableName varchar(32),
    @RowId int
)
RETURNS 
@Log TABLE
(       
    LogId int not null,
    UserId int not null,
    Description varchar(1024) not null
)
AS
BEGIN

INSERT INTO @Log
SELECT     [Log].LogId, [Log].UserId, [Log].Description
FROM         [Log] INNER JOIN
                      LogReference ON [Log].LogId = LogReference.LogId
WHERE     (LogReference.TableName = @TableName) AND (LogReference.RowId = @RowId)
    RETURN 
END
GO
هل كانت مفيدة؟

المحلول

بالتأكيد سأذهب للخيار 3، لعدة أسباب:

يجب أن تكون البيانات في مجالات جدول، وليس كاسم جدول (الخيار 2) أو اسم حقل (الخيار 1). وبهذه الطريقة تصبح قاعدة البيانات أسهل للعمل وأسهل للحفاظ عليها.

الجداول الضيقة أداء genrally أفضل. عدد الصفوف له تأثير أقل على الأداء من عدد الحقول.

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

نصائح أخرى

كن حذرا مع قواعد البيانات المعاد بروتبتثاء. معظم قواعد البيانات سريعة ومعقدة إلى حد ما. تريد تشغيل اختبار للكفاءة أولا.

ثاني وضع كل شيء في طاولة واحدة يجعل من المرجح أن النتائج التي تريدها في ذاكرة التخزين المؤقت التي ستسرع في الأداء بشكل كبير. لسوء الحظ، فإنه يجعل من المرجح أن يتعين عليك البحث عن طاولة عملاقة للعثور على ما تبحث عنه. يمكن حل هذا جزئيا بفهرس، لكن الفهارس لا تأتي مجانا (أنها تجعل الكتابة أكثر تكلفة، لأحد).

ستكون نصيحتي هي إجراء اختبار لمعرفة ما إذا كان الأداء يهم حقا ثم اختبار السيناريوهات المختلفة لمعرفة ما هو الأسرع.

إذا كنت تتحدث عن كميات كبيرة من البيانات (الملايين من الصفوف +)، فستحصل على فائدة من استخدام جداول مختلفة لتخزينها فيها.

مثل المثال الأساسي 50 مليون إدخالات السجل، على افتراض 5 أنواع مختلفة "من جدول السجل أفضل للحصول على 5 × 10 مليون طاولة صف أكثر من 1 × 50 مليون صف

  • سيكون أداء الإدراج أفضل مع الجداول الفردية - ستكون الفهارس الموجودة على كل جدول أصغر وسهل تحديث / الحفاظ عليها كجزء من عملية الإدراج

  • سيكون قراءة الأداء أفضل مع الجداول الفردية - بيانات أقل لاستعلام، مؤشرات أصغر إلى اجتياز. أيضا، يبدو وكأنك بحاجة إلى تخزين عمود إضافي لتحديد نوع سجل الدخول سجل (المنتج، الشحن ....)

  • الصيانة على الجداول الأصغر أقل مؤلمة (إحصائيات، مؤشر تجزئة / إعادة بناء الخ)

أساسا، هذا يدور حول تقسيم البيانات. من SQL 2005 فصاعدا، لقد بنيت في دعم التقسيم (انظر هنا.

لقد استمعت إلى مقابلة مع أحد المهندسين المعماريين في eBay مؤخرا، وشدد على أهمية التقسيم عند الحاجة إلى الأداء والقابلية للتوسع وأنا أتفق بشدة على تجاربي.

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

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

سيكون تفضيلي للخيار 1 راجع للشغل - أبسط للقيام به وهناك عدد من القرص الذي يمكنك القيام به للمساعدة في إصلاح أنواع مختلفة من المشكلات التي قد تكون لديكم.

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