PDA

View Full Version : Index ها



ealireza
سه شنبه 11 بهمن 1384, 11:22 صبح
سلام
من واقعا گیج شدم
اگه میشه کامل توضیح بدین این سه مدل ایندکس که داریم چطوری عمل میکنن

چطوری میشه یک ریلشن رو با اینکس مچ کرد
بطوری که مثلا اطلاعات مربوط به یک کاربر رو که با شماره اون مشخص میشه ایندکس کرد

خواهشا انواع ایندکس (یونک و.. ) رو توضیح بدین


به فارسی لطفا

مرسی

Elham_gh
سه شنبه 11 بهمن 1384, 13:01 عصر
از یک دیدگاه به طور کلی 2 نوع ایندکس داریم : ClusteredوNon-clustered.
هر جدول می تواند 1 ایندکس Clusteredو 246ایندکسNon-clustered داشته باشد.ایندکس Clustered اطلاعات را به صورت فیزیکی مرتب می کند.بدین معنی که نحوه مرتب سازی به صورت B-tree است. هر Node آدرس node قبلی و بعدی خود را دارد ودر Leaf این B-tree اطلاعات مربوط به رکوردها را نیز در خود نگه می دارد. ایندکس Non-clustered از همان ساختار مرتب سازی B-tree استفاده می کند , با 2 فرق.اول اینکه در Leaf این B-tree اطلاعات مربوط به رکوردها را ندارد . بلکه یک آدرس دارد که به Node مورد نظر در B-tree ایندکس Clustered اشاره می کند. و دوم اینکه اطلاعات بر مبنای کلید ایندکس Non-clustered شما مرتب و ذخیره نمی شوند.

از دیدگاه دیگر میتوان تقسیم بندی دیگری برای ایندکس ها داشت :
Primary – Unique –
در ایندکس Primary امکان ورود اطلاعات تکراری و Null در فیلد(های) کلید وجود ندارد. نامگذاری این ایندکس ها معمولا با PK_ شروع می شود.
ایندکس Unique جلوی ورود اطلاعات تکراری در فیلد(های) کلید را می گیرد اما Null را قبول می کند.
شما می توانید ایندکسی نیز داشته باشید که نه primary باشد و نه Unique. نامگذاری این ایندکسها و ایندکس Unique با IX_ شروع می شود.
اما هرکدام از این انواع ایندکس ها باید یا Clustered باشند یا Non-clustered. معمولا ایندکس primary بعنوان ایندکس Clustered در نظر گرفته می شود. اما این اجباری نیست. حتی جدول شما می تواند هیچ ایندکس Clustered نیز نداشته باشد.

کلیدها در ایندکسهای Unique و Primary می توانند کلید خارجی در جداول دیگر باشند.

اگر از طریق Diagram ارتباط بین جداول را بر قرار کنید خودش ایندکس های مربوط به کلیدهای خارجی را ایجاد می کند

AminSobati
سه شنبه 11 بهمن 1384, 19:59 عصر
http://www.barnamenevis.org/forum/showthread.php?t=21774
http://www.barnamenevis.org/forum/showthread.php?t=9498

ealireza
چهارشنبه 12 بهمن 1384, 16:44 عصر
مرسی آقای ثابتی
اونا رو العان خوندم
یجا اشاره کردین به استفاده از دو هارد یکی برا ایندکس و یکی هم برای دیتابیس
اون هاردی که برای ایندکس ها لازمه چطوری باید مشخص بشه ؟
آیا ایندکس ها فایل خاصی ایجاد میکنند ؟


یک سوال دیگه هم داشتم
مثلا برای یک کوئری


Select C_1,C_2,C_3,C_4,C_5 From Tabel Where C_66=1 and C99=3

در این کوئری ما یک C_66 داریم که تو 90% کوئری ها تکرار میشه و یک C_99داریم که فقط تو این کوئری استفاده میشه
ایندکس مناسب چطوری باید ساخته شه ؟
روی C_66 ?
بعد بهترین حالت کدومه
Fill Factor چی هست در کل ؟
برا همچیم کوئری باید روی چند تنظیم شه

لطفا یک چیزی هم در باره Index View بگزراید
مرسی

AminSobati
چهارشنبه 12 بهمن 1384, 21:13 عصر
زمانیکه شما دیتابیس رو ایجاد میکنین، میتونین فایلهای دیتابیس رو در قالب Filegroupهای مجزا بسازید. ساخت فایل های جدید و Filegroup بعدا هم امکان پذیره. لذا اگر یک Filegroup به اسم MyFG1 دارای فایلی روی درایو C باشه و Filegroup دیگری به نام MyFG2 دارای فایلی روی درایو D باشه (با فرض بر اینکه C و D دیسکهای مجزا هستند، نه پارتیشن هایی از یک دیسک) شما میتونین جدول رو روی MyFG1 و ایندکسش رو روی MyFG2 بسازید. اما تصور نکنید که در تمام Queryها این دو هارد دیسک به صورت پارالل کار میکنند. در بعضی از Queryها ممکنه یکی از دیسکها اصلا مورد استفاده قرار نگیره. مثلا با Query که نوشتید، اگر یک ایندکس Nonclustered روی C_66 و C_99 بسازید، در این حالت SQL Server بعد از پیدا کردن هر رکورد در ایندکس(MyFG2) باید رجوع کنه به MyFG1 تا سایر فیلدهای مورد نظر شما رو (C_1, C_2, ....) بدست بیاره. این رجوع کردن رو Boomark Lookup میشناسیم. حالا اگر در فهرست فیلدهای جلوی Select، مثلا فقط فیلد C_99 رو میخواستید (... SELECT C_99 FROM) در این حالت اصلا به جدول رجوع نمیکرد چرا که این فیلد در ایندکس وجود داره. پس دیسک اول که در برگیرنده خود جدول بود اصلا مورد استفاده قرار نگرفت. در بهینه سازی یک Query، باید تا جای ممکن با ساختن ایندکسهای صحیح سعی کنیم Bookmark Lookupها رو حذف کنیم. مثلا اگر در Query شما، فیلدهای C_1 و C_2 و ... در ایندکس وجود داشتند، Bookmark Lookup اتفاق نمیافتاد. ضمنا با داشتن RAID تقریبا نیازی به Filegroup (برای افزایش Performance) ندارید چون Filegroup سعی داره RAID رو شبیه سازی کنه. اما Filegroup منافع دیگری هم تامین میکنه که مورد بحث ما نیست
در مورد بهترین ایندکس ممکن برای Query شما، خوشبختانه وجود AND کمی کار رو راحت میکنه. سعی کنید فیلدی که مقادیر اون به یونیک بودن نزدیک هست رو اول از همه فیلدها در Index قرار بدین. برای این منظور:


SELECT DISTINCT C_66 FROM MyTable
GO
SELECT DISTINCT C_99 FROM MyTable

هر Query که بیشترین Result رو داد، پس فیلد اون رو باید اول از همه در Index لیست کنین. با فرض بر اینکه C_99 این شرط رو داشته باشه:


CREATE NONCLUSTERED INDEX ix_1
ON MyTable(C_99,C_66,C_1,C_2,C_3,C_4,C_5)

من تمام فیلدهای جلوی Select رو در ایندکس گذاشتم با فرض بر اینکه سرعت این Query برای شما بسیار حیاتیه و Bookmark Lookup نباید داشته باشیم. چرا که داشتن این تعداد فیلد در Index طبیعتا حجم بیشتری از فضای دیتابیس رو اشغال میکنه (بسته به اینکه اولویت برای شما چی باشه: سرعت بیشتر یا حجم کمتر. من همیشه طرفدار اولی هستم!)
زمانیکه ایندکس روی یک فیلد ساخته میشه، تمام اطلاعات این فیلد در چند Page مرتب میشن. پس اگر رکورد جدیدی در جدول Insert بشه، ایندکس باید مقدار فیلد مربوطه از رکورد جدید رو در خودش قرار بده، اما در جای صحیح بر حسب Sort Order. اگر Pageها کاملا پر باشند، Page مربوطه باید Split(دو قسمت) بشه و نصف اطلاعات به اولین Page خالی برده بشن (ممکنه اولین Pageخالی بسیار دورتر باشه). رخ دادن Page Split نه تنها خودش رو دیسک I/O اضافی ایجاد میکنه بلکه به خاطر نقل و انتقال Data، به مرور در وضعیت داخلی دیتابیس ناپیوستگی (Fragmentation) بوجود میاد و این = Performance Penalty
پس خوبه که موقع ساخت Index، از SQL Server بخواهیم که 90 درصد از هر Page رو پر کنه تا با ورود اولین مقدار جدید به ایندکس، Page Split رخ نده و 10 درصد فضای خالی فعلا داشته باشیم. اینکه هر Page چقدر پر بشه بهش Fillfactor میگیم. ولی مقدار باقیمانده همیشگی نیست و بعد از مدتی به خاطر عملیات ویرایشی، این فضا کم میشه. به همین دلیل Adminهای عزیز باید Rebuild کردن ایندکسها رو در Check List ماهیانه خودشون قرار بدن.
مقدار Fillfactor به این بستگی داره که جدول شما چقدر ویرایش میشه. برای اطلاعات Read Only مقدار 100 درصد، برای اطلاعات Read Mostly حدود 93 درصد و برای اطلاعاتی که به شدت تحت ویرایش قرار دارند بین 75 تا 80 درصد مناسبه. تصور نکنید اگر Fillfactor رو پایین بگیرید، تا مدتها نگران نیستید... نه، بلکه Fillfactor پایین باعث میشه اولا حجم ایندکس شما غیر عادی بشه و از طرفی اطلاعات ایندکس در تعداد Pageهای بیشتری توزیع میشه و این موقع دسترسی به ایندکس، I/O مضاعف تولید میکنه و به Performance لطمه میزنه.
در خصوص Indexed View: زمانیکه یک View میسازید و ازش Query میگیرید، شرطی که در داخل View وجود داره با شرطی که بیرون از View هست (مربوط به Select شما از View) با هم ادغام (Materialized) میشن و Query داخل View واقعا اجرا میشه. ولی وقتی روی View یک ایندکس بسازید، نتیجه Select داخل View واقعا بصورت فیزیکی در دیسک ذخیره میشه و وقتی از View یک Query بگیرید، تقریبا Result شما از قبل حاضره! وقتی Base Tableها (جداولی که View به اونها نیاز داره) مورد ویرایش قرار بگیرند، ایندکس ساخته شده بر روی View به روز میشه. هر Viewیی قابلیت Index زدن رو نداره. برای دیدن شرایطش به BOL رجوع کنین. بسیاری از محدودیت ها در SQL Server 2005 حذف شده و دست شما باز تره.
شاد و پیروز باشید

ealireza
چهارشنبه 12 بهمن 1384, 22:18 عصر
واقعا دستتون درد نکنه تا حالا همچین توضیح کاملی ندیده بودم
کاربرد Fillfactor رو کاملا متوجه شدم
مرسی

فقط آخرین سوال من اینه که


Select C_1,C_2,C_3,C_4,C_5,C_6 From Tabel Where C_66=1 and C99=3 and c_88=2

این C_6 و شرط C_88=2 چقدر باعث کند میشن (اونها رو ایندکس نمیکنیم)

و استاد اگه میشه یک کتاب خوب SQL معرفی کنید خریداری کنیم اطلاعاتمون بیشتر بشه


با تشکر فراوان