টিএসকিউএল পারফরম্যান্স - মিনিট এবং সর্বাধিক মান ব্যয় করুন


10

আমার দুটি টেবিল রয়েছে যেখানে আমি সঞ্চয় করি:

  • একটি আইপি পরিসীমা - দেশ দেখার সারণী
  • বিভিন্ন আইপি থেকে আসা অনুরোধগুলির একটি তালিকা

আইপিগুলি লুকিং bigintপারফরম্যান্সের উন্নতির জন্য সংরক্ষণ করা হয়েছিল ।

এটি টেবিল কাঠামো:

create table [dbo].[ip2country](
    [begin_ip] [varchar](15) NOT NULL,
    [end_ip] [varchar](15) NOT NULL,
    [begin_num] [bigint] NOT NULL,
    [end_num] [bigint] NOT NULL,
    [IDCountry] [int] NULL,
    constraint [PK_ip2country] PRIMARY KEY CLUSTERED 
    (
        [begin_num] ASC,
        [end_num] ASC
    )
)

create table Request(
    Id int identity primary key, 
    [Date] datetime, 
    IP bigint, 
    CategoryId int
)

আমি প্রতি দেশটিতে অনুরোধের ব্রেকডাউন পেতে চাই, তাই আমি নিম্নলিখিত কোয়েরিটি সম্পাদন করি:

select 
    ic.IDCountry,
    count(r.Id) as CountryCount
from Request r
left join ip2country ic 
  on r.IP between ic.begin_num and ic.end_num
where r.CategoryId = 1
group by ic.IDCountry

আমার টেবিলে প্রচুর রেকর্ড রয়েছে: প্রায় 200,000 ইন IP2Countryএবং কয়েক মিলিয়ন Request, সুতরাং ক্যোয়ারিতে কিছুটা সময় লাগে takes

এক্সিকিউশন পরিকল্পনার দিকে তাকিয়ে, সর্বাধিক ব্যয়বহুল অংশ হ'ল একটি ক্লাস্টারড ইনডেক্স সিক ইনডেক্স পিকে_আইপি 2 দেশটিতে, যা বহুবার কার্যকর করা হয় (অনুরোধে সারিগুলির সংখ্যা)।

এছাড়াও, আমি যে বিষয়টি সম্পর্কে কিছুটা অদ্ভুত বোধ left join ip2country ic on r.IP between ic.begin_num and ic.end_numকরি তা হ'ল অংশ (অনুসন্ধানটি করার আরও ভাল উপায় আছে কিনা তা জানেন না)।

টেবিল কাঠামো, কিছু নমুনা ডেটা এবং ক্যোয়ারী এসকিউএলফিডেলে উপলব্ধ: http://www.sqlfiddle.com/#!3/a463e/3 (দুর্ভাগ্যক্রমে আমি মনে করি না যে সমস্যাটি পুনরুত্পাদন করতে আমি অনেকগুলি রেকর্ড সন্নিবেশ করতে পারি, তবে এটি আশা করি একটি ধারণা দেয়)।

আমি (স্পষ্টতই) এসকিউএল পারফরম্যান্স / অপ্টিমাইজেশনে বিশেষজ্ঞ নই, সুতরাং আমার প্রশ্নটি: এই কাঠামো / ক্যোয়ারীটি যে আমি অনুপস্থিত তা পারফরম্যান্স-ভিত্তিতে উন্নত করার কোনও স্পষ্ট উপায় আছে কি?


2
আইপি ঠিকানা মানচিত্র একাধিক দেশে করতে পারেন? যদি তা না হয় তবে আপনি আপনার পিকে সংকুচিত করতে পারেন begin_num। আমাকে A BETWEEN B AND Cপ্রায়শই প্রায় যোগ দিতে হয় এবং ক্লান্তিকর আরবিএআর যোগদান না করে এটি অর্জনের কোনও উপায় আছে কিনা তা জানতে আগ্রহী।
সমস্ত ট্রেডের জোন

1
এটি আপনার প্রশ্নের সামান্য বিষয়বস্তু, তবে পাঠ্য এবং সংখ্যাগুলি কোনওভাবে সিঙ্ক থেকে বেরিয়ে আসার সম্ভাবনা রোধ করার জন্য, আমি গণনাকৃত কলামগুলি তৈরি begin_ipএবং ধরে রাখতে বিবেচনা করব end_ip
সমস্ত ট্রেডের জোন

@ w0lf: ওভারল্যাপিং রেঞ্জগুলি কি এখানে রয়েছে ip2country (begin_num, end_num)?
ypercubeᵀᴹ

@ জোনফএল ট্রেডস সাধারণত একটি আইপি একক দেশের অন্তর্ভুক্ত হওয়া উচিত, সুতরাং আমি মনে করি যে give me the first record that has a begin_num < ip in asc order of begin_num( যেমন আমি ভুল হলে আমাকে সংশোধন করুন) এর মতো আপনার ক্যোয়ারী সম্পর্কে ধারণাটি বৈধ হতে পারে এবং কর্মক্ষমতা উন্নত করতে পারে।
ক্রিশ্চিয়ান লুপাস্কু

1
@ ডাব্লু0এলএফ: আমার ইমপ্রেশনটি হ'ল মূলত সার্ভারটি এরকম একটি ক্ষেত্রে কী করছে কারণ এটি প্রথমে স্ক্যান করে begin_num, তারপরে end_numসেটের মধ্যে স্ক্যান করে কেবল একটি রেকর্ড খুঁজে পায়।
সমস্ত ব্যবসায়ের জন

উত্তর:


3

আপনার একটি অতিরিক্ত সূচি দরকার। আপনার ফিডাল উদাহরণে আমি যুক্ত করেছি:

CREATE UNIQUE INDEX ix_IP ON Request(CategoryID, IP)

যা আপনাকে অনুরোধ সারণির জন্য কভার করে এবং একটি ক্লাস্টারড ইনডেক্স স্ক্যানের পরিবর্তে একটি সূচক সন্ধান করে।

এটি কীভাবে এটির উন্নতি করে তা আমাকে জানান। আমি অনুমান করছি যে এটি অনেকটা সহায়তা করবে যেহেতু সেই সূচকের স্ক্যানটি নিশ্চিত যে আমি সস্তা না।


কেন জানি না, তবে ফলাফলগুলি আলাদা বলে মনে হচ্ছে (এসকিউএলফিডেলে)
ক্রিশ্চিয়ান লুপাস্কু

@ w0lf: এগুলি পৃথক (সম্ভাব্য) কারণ আপনি উভয়ই টেবিলগুলিতে এলোমেলো ডেটা areোকাচ্ছেন।
ypercubeᵀᴹ

@ টাইপ्यूब অবশ্যই এটি কারণ। আমি ইদানীং অনেকগুলি কাজ করেছি যে আমি ভুলে গিয়েছিলাম যে ডেটা এলোমেলো ছিল। দুঃখিত।
ক্রিশ্চিয়ান লুপাস্কু

2

সর্বদা হিংস্র শক্তি প্রয়োগ রয়েছে: আপনি আপনার আইপি মানচিত্রটি বিস্ফোরণ করতে পারেন। প্রতিটি আইপি ঠিকানার জন্য একটি রেকর্ড তৈরি করতে আপনার বিদ্যমান মানচিত্রের বিপরীতে একটি সংখ্যা সারণীতে যোগদান করুন। আপনার ফিডাল ডেটার উপর ভিত্তি করে এটি কেবল 267 কে রেকর্ডস, কোনও সমস্যা নেই।

CREATE TABLE IPLookup
  (
  IP  BIGINT PRIMARY KEY,
  CountryID  INT
  )
INSERT INTO IPLookup (IP, CountryID)
  SELECT
    N.Number, Existing.IDCountry
  FROM
    ip2country AS Existing
    INNER JOIN Numbers AS N ON N.Number BETWEEN Existing.begin_num AND Existing.end_num

এটি সিকাকে আরও সহজ এবং আশা করি দ্রুততর করে তুলবে। এটি ip2countryঅবশ্যই যদি আপনি অবশ্যই তুলনামূলকভাবে কয়েকটি আপডেট করেন তবে তা বোধগম্য হয় ।

আমি আশা করি অন্য কারওর থেকে ভাল সমাধানের সমাধান আছে!


পুরো ডেটা সেটটি 5 বিলিয়নেরও বেশি রেকর্ড তৈরি করবে, তাই আমি মনে করি না এটি করব। তবে এটি তবুও একটি দুর্দান্ত ধারণা; আমি নিশ্চিত এটি একই রকম অনেক ক্ষেত্রেই সম্ভব। +1
ক্রিশ্চিয়ান লুপাস্কু

0

এটা চেষ্টা কর:

SELECT ic.IDCountry,
        COUNT(r.Id) AS CountryCount
FROM Request r
INNER JOIN (SELECT begin_num+NUMS.N [IP], IDCountry 
            FROM ip2country
            CROSS JOIN (SELECT TOP(SELECT ABS(MAX(end_num-begin_num)) FROM ip2country) ROW_NUMBER() OVER(ORDER BY sc.name)-1 [N]
                        FROM sys.columns sc) NUMS
            WHERE begin_num+NUMS.N <= end_num) ic
ON r.IP = ic.IP
WHERE r.CategoryId = 1
GROUP BY ic.IDCountry

ধন্যবাদ, আমি আপনার পদ্ধতির চেষ্টা করেছি, তবে প্রাথমিক জিজ্ঞাসার চেয়ে এটি ব্যয়বহুল বলে মনে হচ্ছে
ক্রিশ্চিয়ান লুপাস্কু

প্রতিটি টেবিলে আপনার কত সারি রয়েছে? আমি আমার ডিবিতে আপনার সমস্যার স্কেল পুনরুত্পাদন করতে চাই এবং একটি সূচি যোগ না করেই সমাধানের চেষ্টা করতে চাই :)
ভিন্স পার্গোলিজি

আইপি 2 দেশটিতে প্রায় 200,000 এবং অনুরোধে কয়েক মিলিয়ন (সম্ভবত অদূর ভবিষ্যতে কয়েক মিলিয়ন)। আমি মনে করি আপনি যদি
সূচিগুলি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.