লিনকিউইউ WHERE এর সাথে লিঙ্ক করার চেয়ে এত দ্রুত কেন যোগ দেয়?


99

আমি সম্প্রতি ভিএস ২০১০-তে আপগ্রেড করেছি এবং লিনকুইয়ের সাথে ডেটাসেটে প্রায় খেলছি। অনুমোদনের জন্য আমার কাছে শক্তিশালী টাইপ করা ডেটাसेट রয়েছে যা একটি এএসপি.নেট ওয়েব অ্যাপ্লিকেশনটির এইচটিপিচিতে রয়েছে।

সুতরাং আমি জানতে চেয়েছিলাম যে ব্যবহারকারী কোনও কিছুর জন্য অনুমোদিত কিনা তা যাচাই করার দ্রুততম উপায়টি। কারও আগ্রহী হলে এখানে আমার ডেটামোডেল এবং অন্যান্য কিছু তথ্য।

আমি 3 টি উপায় পরীক্ষা করেছি:

  1. সরাসরি ডাটাবেস
  2. সঙ্গে LINQ ক্যোয়ারী কোথায় হিসাবে "যোগদান করুন" অবস্থা - সিনট্যাক্স
  3. যোগদান - সিনট্যাক্স সহ লাইনকিউ ক্যোয়ারী

প্রতিটি ফাংশনে 1000 টি কল সহ এগুলি ফলাফল:

1. সূচনা:

  1. 4,2841519 সেকেন্ড
  2. 115,7796925 সেকেন্ড।
  3. 2,024749 সেকেন্ড

2.Iteration:

  1. 3,1954857 সেকেন্ড
  2. 84,97047 সেকেন্ড।
  3. 1,5783397 সেকেন্ড

3.Iteration:

  1. 2,7922143 সেকেন্ড
  2. 97,8713267 সেকেন্ড।
  3. 1,8432163 সেকেন্ড

গড়:

  1. ডাটাবেস: 3,4239506333 সেকেন্ড
  2. যেখানে: 99,5404964 সেকেন্ড
  3. যোগদান করুন: 1,815435 সেকেন্ড

যোগ-সংস্করণটি যেখানে-সিনট্যাক্সের চেয়ে এত দ্রুত কেন এটি একটি অকেজো করে তোলে যদিও লিনকিউ নবাগত হিসাবে এটি সবচেয়ে সুস্পষ্ট বলে মনে হয়। অথবা আমি আমার প্রশ্নের কিছু মিস করেছি?

এখানে লিনকিউ প্রশ্নগুলি রয়েছে, আমি ডাটাবেসটি এড়িয়ে চলেছি:

কোথায় :

Public Function hasAccessDS_Where(ByVal accessRule As String) As Boolean
    Dim userID As Guid = DirectCast(Membership.GetUser.ProviderUserKey, Guid)
    Dim query = From accRule In Authorization.dsAuth.aspnet_AccessRule, _
                roleAccRule In Authorization.dsAuth.aspnet_RoleAccessRule, _
                role In Authorization.dsAuth.aspnet_Roles, _
                userRole In Authorization.dsAuth.aspnet_UsersInRoles _
                Where accRule.idAccessRule = roleAccRule.fiAccessRule _
                And roleAccRule.fiRole = role.RoleId _
                And userRole.RoleId = role.RoleId _
                And userRole.UserId = userID And accRule.RuleName.Contains(accessRule)
                Select accRule.idAccessRule
    Return query.Any
End Function

যোগদান:

Public Function hasAccessDS_Join(ByVal accessRule As String) As Boolean
    Dim userID As Guid = DirectCast(Membership.GetUser.ProviderUserKey, Guid)
    Dim query = From accRule In Authorization.dsAuth.aspnet_AccessRule _
                Join roleAccRule In Authorization.dsAuth.aspnet_RoleAccessRule _
                On accRule.idAccessRule Equals roleAccRule.fiAccessRule _
                Join role In Authorization.dsAuth.aspnet_Roles _
                On role.RoleId Equals roleAccRule.fiRole _
                Join userRole In Authorization.dsAuth.aspnet_UsersInRoles _
                On userRole.RoleId Equals role.RoleId _
                Where userRole.UserId = userID And accRule.RuleName.Contains(accessRule)
                Select accRule.idAccessRule
    Return query.Any
End Function

তুমাকে অগ্রিম ধন্যবাদ.


সম্পাদনা করুন : আরও অর্থপূর্ণ পারফরম্যান্স-মান পেতে উভয় প্রশ্নের কিছু উন্নতি করার পরে, JOIN এর সুবিধা আগের চেয়ে অনেক গুণ বেশি:

যোগদান :

Public Overloads Shared Function hasAccessDS_Join(ByVal userID As Guid, ByVal idAccessRule As Int32) As Boolean
    Dim query = From accRule In Authorization.dsAuth.aspnet_AccessRule _
                   Join roleAccRule In Authorization.dsAuth.aspnet_RoleAccessRule _
                   On accRule.idAccessRule Equals roleAccRule.fiAccessRule _
                   Join role In Authorization.dsAuth.aspnet_Roles _
                   On role.RoleId Equals roleAccRule.fiRole _
                   Join userRole In Authorization.dsAuth.aspnet_UsersInRoles _
                   On userRole.RoleId Equals role.RoleId _
                   Where accRule.idAccessRule = idAccessRule And userRole.UserId = userID
             Select role.RoleId
    Return query.Any
End Function

কোথায় :

Public Overloads Shared Function hasAccessDS_Where(ByVal userID As Guid, ByVal idAccessRule As Int32) As Boolean
    Dim query = From accRule In Authorization.dsAuth.aspnet_AccessRule, _
           roleAccRule In Authorization.dsAuth.aspnet_RoleAccessRule, _
           role In Authorization.dsAuth.aspnet_Roles, _
           userRole In Authorization.dsAuth.aspnet_UsersInRoles _
           Where accRule.idAccessRule = roleAccRule.fiAccessRule _
           And roleAccRule.fiRole = role.RoleId _
           And userRole.RoleId = role.RoleId _
           And accRule.idAccessRule = idAccessRule And userRole.UserId = userID
           Select role.RoleId
    Return query.Any
End Function

1000 টি কল (দ্রুত কম্পিউটারে) এর ফলাফল

  1. যোগ দিন | 2. কোথায়

1. সূচনা:

  1. 0,0713669 সেকেন্ড
  2. 12,7395299 সেকেন্ড

2.Iteration:

  1. 0,0492458 সেকেন্ড
  2. 12,3885925 সেকেন্ড

3.Iteration:

  1. 0,0501982 সেকেন্ড
  2. 13,3474216 সেকেন্ড

গড়:

  1. যোগদান: 0,0569367 সেকেন্ড।
  2. যেখানে: 12,8251813 সেকেন্ড

যোগদান 225 গুণ দ্রুত হয়

উপসংহার: সম্পর্কগুলি নির্দিষ্ট করতে ও যেখানেই সম্ভব যোগ দানের জন্য নিখুঁতভাবে এড়িয়ে চলুন (স্পষ্টতই লিনকিউতে ডেটাসেটে এবং Linq-To-Objectsসাধারণভাবে)।


অন্যেরা যারা এটি পড়েছেন এবং লিনকটিএসকিউএল ব্যবহার করছেন এবং মনে করেন যে আপনার সমস্ত WHEE গুলি জোয়িনে পরিবর্তন করা ভাল হতে পারে, দয়া করে নিশ্চিত করুন যে আপনি থমাস লেভেস্কের মন্তব্যটি পড়েছেন যেখানে তিনি বলেছেন "আপনি যখন এসকিউএল-তে লিনক ব্যবহার করেন তখন এমন অপ্টিমাইজেশন রয়েছে বা লিনক টু সত্তা, কারণ উত্পন্ন এসকিউএল কোয়েরিটি ডিবিএমএস দ্বারা যোগদান হিসাবে বিবেচিত হয়। তবে সেই ক্ষেত্রে আপনি লিনক ডেটাসেটে ব্যবহার করছেন, এসকিউএল-তে কোনও অনুবাদ নেই "। অন্য কথায়, আপনি যখন লিনকটোসক্লল ব্যবহার করছেন তখন WHEE এর অনুবাদ হিসাবে যোগদান করে anything
জোনএইচ

@ জোনএইচ: এটি Joinযেভাবেই ব্যবহার করতে ক্ষতিগ্রস্থ হয় না , আপনি যদি প্রথম থেকেই অপটিমাইজড কোডটি লিখতে পারেন তবে কেন কোনও অপ্টিমাইজারের উপর নির্ভর করবেন? এটি আপনার উদ্দেশ্যগুলি আরও পরিষ্কার করে দেয়। সুতরাং একই কারণে আপনার স্কয়ারে JOIN পছন্দ করা উচিত
টিম শ্মেলেটার

আমি কী ধরে নিচ্ছি যে এন্টি ফ্রেমওয়ার্কের ক্ষেত্রে এটি হবে না?
মাফাই

উত্তর:


76
  1. আপনার প্রথম পদ্ধতির (ডিবিতে এসকিউএল ক্যোয়ারী) যথেষ্ট দক্ষ কারণ ডিবি কীভাবে যোগদান করতে হয় তা জানে। তবে এগুলি অন্যান্য পদ্ধতির সাথে তুলনা করা সত্যিকার অর্থে বোধগম্য নয়, যেহেতু তারা সরাসরি স্মৃতিতে কাজ করে (লিঙ্ক থেকে ডেটাসেট)

  2. একাধিক সারণী এবং Whereশর্তযুক্ত ক্যোয়ারীটি সমস্ত টেবিলের কার্টেসিয়ান পণ্য সম্পাদন করে, তারপরে শর্তটি পূরণ করে এমন সারিগুলি ফিল্টার করে। এর অর্থ Whereশর্তগুলির প্রতিটি সংমিশ্রণের জন্য মূল্যায়ন করা হয় (n1 * n2 * n3 * n4)

  3. Joinঅপারেটর, প্রথম টেবিল থেকে সারি লাগে তারপর দ্বিতীয় টেবিল থেকে একটি মানানসই কী, তারপর শুধুমাত্র তৃতীয় টেবিল থেকে একটি মানানসই কী দিয়ে সারি, এবং তাই একমাত্র সারি লাগে। এটি অনেক বেশি দক্ষ, কারণ এটি যতগুলি অপারেশন করার দরকার নেই


4
পটভূমি স্পষ্ট করার জন্য আপনাকে ধন্যবাদ। ডিবি অ্যাপ্রোচটি সত্যই এই প্রশ্নের অংশ ছিল না, তবে মেমরির পদ্ধতির সত্যই দ্রুততর কিনা তা আমার কাছে আকর্ষণীয় ছিল। আমি ধরে নিয়েছি। নেট whereকোনওভাবে একটি ডিবিএম হিসাবে জিজ্ঞাসাকে অনুকূল করে তুলবে। প্রকৃতপক্ষে এটি (শেষ সম্পাদনা) এর JOINচেয়ে 225 গুণ বেশি দ্রুত ছিল WHERE
টিম শেমলেটার

19

Joinকারণ পদ্ধতি জানে টেবিল একত্রিত করতে কিভাবে প্রাসঙ্গিক সমন্বয় করতে ফলাফলকে লঘু করতে, অনেক দ্রুততর। আপনি যখন ব্যবহারWhere সম্পর্কটি নির্দিষ্ট করেন, তখন এটি প্রতিটি সম্ভাব্য সংমিশ্রণ তৈরি করতে হবে এবং তারপরে কোন সম্মিলনগুলি প্রাসঙ্গিক তা দেখতে শর্তটি পরীক্ষা করতে হবে।

দ্রুত Joinদুটি জিপ দুটি দ্রুত একসাথে জিপ করতে সূচি হিসাবে ব্যবহার করতে পদ্ধতিটি একটি হ্যাশ টেবিল সেট আপ করতে পারে, যখন Whereপদ্ধতিটি সমস্ত সংমিশ্রণ ইতিমধ্যে তৈরি হওয়ার পরে চলে, সুতরাং এটি পূর্বে সংযুক্তিগুলি হ্রাস করার জন্য কোনও কৌশল ব্যবহার করতে পারে না।


ধন্যবাদ. সংকলক / রানটাইম থেকে ডিবিএমএসের মতো কোনও অন্তর্নিহিত অপ্টিমাইজেশন নেই? বাস্তবে যে সম্পর্কটি যুক্ত হচ্ছে তা দেখা অসম্ভব হবে না।
টিম শেমলেটার

4
একটি ভাল আরডিবিএমএস প্রকৃতপক্ষে স্পট করা উচিত যেখানে দুটি অনন্য কলামে সমতা জন্য শর্তটি একটি পরীক্ষা এবং এটি একটি যোগদান হিসাবে বিবেচনা করে।
সাইমন রিখটার

6
@ টিম স্কেল্টার, আপনি লিনক থেকে এসকিউএল বা লিনক টু সত্তাগুলি ব্যবহার করার সময় এ জাতীয় একটি অপ্টিমাইজেশন রয়েছে কারণ উত্পন্ন এসকিউএল কোয়েরিটিকে ডিবিএমএস দ্বারা যোগদান হিসাবে বিবেচনা করা হয়। তবে সেক্ষেত্রে আপনি লিনক ডেটাসেটে ব্যবহার করছেন, এসকিউএল
টমাস লেভস্ক

@ টিম: লাইনকিউ থেকে ডেটাসেটস আসলে লিনকিউ টু অবজেক্টস ব্যবহার করে। ফলস্বরূপ, সত্যিকারের সাথে যোগ দিয়ে কেবল joinকীওয়ার্ডটিই ধরা যায় , কারণ একটি কার্যকর করার পরিকল্পনার সাথে সামঞ্জস্যপূর্ণ কিছু উত্পাদন করার জন্য ক্যোয়ারির কোনও রানটাইম বিশ্লেষণ নেই। আপনি আরও খেয়াল করতে পারেন যে লিনকিউ-ভিত্তিক যোগদানগুলি কেবলমাত্র একক-কলামের সমতুল্য স্থানগুলিতে থাকতে পারে।
অ্যাডাম রবিনসন

4
@ অ্যাডাম, এটি একেবারেই সত্য নয়: আপনি বেনামে বিভিন্ন ধরণের সাহায্যে একাধিক কী দিয়ে সমীকরণ করতে পারেন:... on new { f1.Key1, f1.Key2 } equals new { f2.Key1, f2.Key2 }
টমাস লেভস্ক

7

আপনার সত্যিকারের যা জানা দরকার তা হল দুটি স্কেটমেন্টের জন্য তৈরি করা স্কেল। এটিতে যাওয়ার কয়েকটি উপায় রয়েছে তবে লিনকপ্যাডটি ব্যবহার করা সবচেয়ে সহজ। কোয়েরির ফলাফলের ঠিক উপরে বেশ কয়েকটি বোতাম রয়েছে যা স্কেলে পরিবর্তিত হবে। এটি আপনাকে অন্য যে কোনও কিছুর চেয়ে অনেক বেশি তথ্য দেবে।

আপনি সেখানে ভাগ করে নেওয়ার দুর্দান্ত তথ্য।


4
লিনকপ্যাড-ইঙ্গিতের জন্য ধন্যবাদ প্রকৃতপক্ষে আমার দুটি প্রশ্নগুলি মেমোরি ক্যোয়ারীতে ডেটাসেটের লিনকিউ হয়, অতএব আমি ধরে নিই যে কোনও এসকিউএল উত্পন্ন হয়নি। সাধারণত এটি ডিবিএমএস দ্বারা অনুকূলিত হবে।
টিম শ্মেলেটার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.