Arşiv

Etiketlenen yazılar join

Sql Server Identity Sutunları Belirlemek

20 Nisan 2011 Yorum yapılmamış

BilgeAdam’daki eski öğrencilerimden biri şu soruyu sordu; “Herhangi bir veritabanındaki tüm tablolarda bulunan Identity Sütunları belirlemenin bir yolu var mıdır?”

Aslında bir değil, tam üç yolu var;

Yöntem 1 : COLUMNPROPERTY fonksiyonunu kullanmak

SELECT
	TABLE_NAME,
	COLUMN_NAME
FROM
	INFORMATION_SCHEMA.COLUMNS
WHERE
	COLUMNPROPERTY(OBJECT_ID(TABLE_NAME), COLUMN_NAME, 'ISIDENTITY') = 1
ORDER BY
	TABLE_NAME

Yöntem 2 : SYS.ALL_COLUMNS View’unu kullanmak

SELECT
	OBJECT_NAME(AC.OBJECT_ID),
	SO.NAME
FROM
	SYS.ALL_COLUMNS AS AC
	INNER JOIN SYS.OBJECTS AS SO ON OBJECT_NAME(AC.OBJECT_ID) = SO.NAME
WHERE
	AC.IS_IDENTITY = 1 AND
	SO.TYPE = 'U'

Aynı yöntemi biraz faklı olarak şöyle de yazabiliriz;

SELECT
	OBJECT_NAME(OBJECT_ID),
	NAME
FROM
	SYS.ALL_COLUMNS
WHERE
	IS_IDENTITY = 1 AND
	OBJECTPROPERTY(OBJECT_ID, 'ISUSERTABLE') = 1

Yöntem 3 : SYS.IDENTITY_COLUMNS View’unu kullanmak

SELECT
	OBJECT_NAME(IC.OBJECT_ID),
	SO.NAME
FROM
	sys.identity_columns AS IC
	INNER JOIN SYS.OBJECTS AS SO ON OBJECT_NAME(IC.OBJECT_ID) = SO.NAME
WHERE
	SO.TYPE = 'U'

Aynı yöntemi biraz faklı olarak şöyle de yazabiliriz;

SELECT
	OBJECT_NAME(OBJECT_ID),
	NAME
FROM
	sys.identity_columns
WHERE
	OBJECTPROPERTY(OBJECT_ID, 'ISUSERTABLE') = 1

Bu kodda ne yanlış var? – 6

03 Eylül 2010 3 yorum

Bir kitabevi için web uygulaması geliştiriyorsunuz. Yaptığınız analize dayanarak, uygulamanın veritabanını aşağıdaki gibi tasarladınız;

Bu kodda ne yanlış var? - 6 / Veritabanı Modeli

Veritabanı modelinize göre, her kitabın sıfır veya daha fazla yazarı olabilir, her yazarın sıfır veya daha fazla kitabı olabilir.

Toplam Kitap Adedi ve Toplam Yazar Adedi sorularına cevap verebilmek için, aşağıdaki sorguyu yazdınız;

SELECT DISTINCT
	COUNT(Yazarlar.YazarID) AS ToplamYazarAdedi,
	COUNT(Kitaplar.KitapID) AS ToplamKitapAdedi
FROM
	Yazarlar
	FULL JOIN YazarKitaplari YK ON Yazarlar.YazarID = YK.YazarID
	FULL JOIN Kitaplar ON YK.KitapID = Kitaplar.KitapID

Problem, rakamların beklediğinizden yüksek çıkması.

Sizce problem nedir ve nasıl düzeltebiliriz?

Sql Server Where ve Join Filtreleri Karşılaştırma

26 Ocak 2010 2 yorum

Bilgisayar Programcılığı dünyasında genellikle bir işi yapmanın birden fazla yolu vardır. Özellikle veritabanı tarafında bu yollar daha da fazla olabilir. Uygulama Geliştiriciler olarak yeni bir kod parçası yazacağımız zaman, genellikle bu yollardan en çok kullandığımız bir tanesini seçeriz ve onu kullanırız.

Ne var ki, seçtiğimiz yol herzaman en doğru yol olmayabilir. Sql‘de join‘li sorgulama yaparken, filtreleme için kullandığımız yöntem de bunlardan biri olabilir.

Bu yazımda join‘li sorgularda filtreleme için seçebileceğimiz iki yolu karşılaştıracağım. Karşılaştırma yapmak için kendi bilgisayarımda kurulu olan Sql Server 2008 üzerinde AdventureWorkd2008 R2 veritabanını kullandım.

Eğer birden fazla tablonun join‘ler ile ilişkilendirildiği bir sorgu yazıyorsak, sonuç kümesini filtreleme için kullanabileceğimiz iki yöntem vardır;

WHERE Filtreleme

Sonuç kümesinde olmasını/olmamasını istediğimiz kayıtları sorgunun WHERE cümlesinde tanımlarız. Şablon;

SELECT
	[TABLE1.ALANADLARI],
	[TABLE2.ALANADLARI]
FROM
	[TABLE1]
	JOIN [TABLE2] ON [TABLE1.ALAN1] = [TABLE2.ALAN1]
WHERE
	[TABLE1.ALAN2] = DEGER AND
	[TABLE2.ALAN2] = DEGER

JOIN Filtreleme

Sonuç kümesinde olmasını/olmamasını istediğimiz kayıtları sorgunun JOIN cümlelerinde tanımlarız. Şablon;

SELECT
	[TABLE1.ALANADLARI],
	[TABLE2.ALANADLARI]
FROM
	[TABLE1]
	JOIN [TABLE2] ON [TABLE1.ALAN1] = [TABLE2.ALAN1] AND [TABLE1.ALAN2] = DEGER AND [TABLE2.ALAN2] = DEGER

AdventureWorks2008 R2 veritabanında aşağıdaki iki sorguyu çalıştırdıktan sonra, performans analizini yapalım;

WHERE Filtreleme

SELECT
	*
FROM
	Sales.SalesOrderHeader AS SOH WITH (NOLOCK)
	JOIN Sales.SalesOrderDetail AS SOD WITH (NOLOCK) ON SOH.SalesOrderID = SOD.SalesOrderID
	JOIN Sales.SalesOrderHeaderSalesReason AS SOHSR WITH (NOLOCK) ON SOHSR.SalesOrderID = SOH.SalesOrderID
	JOIN Sales.SalesReason AS SR WITH (NOLOCK) ON SOHSR.SalesReasonID = SR.SalesReasonID
WHERE
	SOH.CustomerID > 15000 AND
	SOD.LineTotal > 2000 AND
	SR.SalesReasonID > 5

JOIN Filtreleme

SELECT
	*
FROM
	Sales.SalesOrderHeader AS SOH WITH (NOLOCK)
	JOIN Sales.SalesOrderDetail AS SOD WITH (NOLOCK) ON SOH.SalesOrderID = SOD.SalesOrderID AND SOH.CustomerID > 15000 AND SOD.LineTotal > 2000
	JOIN Sales.SalesOrderHeaderSalesReason AS SOHSR WITH (NOLOCK) ON SOHSR.SalesOrderID = SOH.SalesOrderID
	JOIN Sales.SalesReason AS SR WITH (NOLOCK) ON SOHSR.SalesReasonID = SR.SalesReasonID AND SR.SalesReasonID > 5

Her iki sorgu da çalıştıktan sonra 1321 satır geri döndürdü. Performans incelemesini üç alanda yapacağız;

  • CPU Kullanımı
  • Disk Kullanımı
  • Hafıza Kullanımı

Bu üç performans kriteri için verileri  SYS.SYSPROCESSES DMV‘sinden alabiliriz. SYS.SYSPROCESSES için detaylı bilgiye MSDN‘deki şu makaleden ulaşabilirsiniz. Aşağıda ilgili üç performans kriteri için verileri elde edebileceğimiz sorgu var;

SELECT
	DB_NAME(SP.DBID) AS VERITABANI,
	EST.TEXT AS SORGU,
	CPU,
	PHYSICAL_IO AS DISK_OKUMA,
	MEMUSAGE AS HAFIZA_KULLANIM
FROM
	SYS.SYSPROCESSES AS SP
	CROSS APPLY SYS.DM_EXEC_SQL_TEXT(SP.SQL_HANDLE) AS EST

Bu sorguyu çalıştırdıktan sonra benim test bilgisayarımda şu verileri elde ettim;

  • VERITABANI : AdventureWorks2008R2
  • CPU : 1965
  • DISK_OKUMA : 211
  • HAFIZA_KULLANIM : 2
  • VERITABANI : AdventureWorks2008R2
  • CPU : 156
  • DISK_OKUMA : 0
  • HAFIZA_KULLANIM : 2

Gördüğünüz gibi kaynak kullanımı açısından (özellikle Disk Okuma ve CPU Kullanımı açısından) JOIN Filtreleme, WHERE Filtrelemeden daha avantajlı.

JOIN Filtreleme tabloları eşlerken filtrelenmiş verileri kullanıyor, WHERE Filtreleme ise, önce tabloları eşleştiriyor sonra filtreliyor. Özellikle çok kayıt bulunan/bulunacak olan tablolarınıza sorgu yazarken, JOIN Filtreleme’yi kullanmanızı tavsiye ederim.

Sql Server’da En Meşgul Veritabanını Bulmak

15 Ocak 2010 Yorum yapılmamış

Geçenlerde bir öğrencimin sorusu üzerine Sql Server’da en meşgul veritabanını nasıl bulabiliriz, sorusuna cevap arayacağız.

En meşgul veritabanı, muhtemelen en çok disk operasyonu yapan veritabanıdır diye düşünerek, en çok disk aktivitesinde bulunan veritabanını yakalamaya çalışmalıyız.

Sql Server ile ilgili aradığımız birçok sorunun cevabını DMV‘lerde olduğu için, öncelikle logical_read ve logical_write miktarlarını veren DMV bulmalıyız.

MSDN’de şu sayfadan detaylı bilgiye ulaşabileceğiniz SYS.DM_EXEC_QUERY_STATS, ihtiyacımız olan TOTAL_LOGICAL_READS, TOTAL_LOGICAL_WRITES, SQL_HANDLE isminde üç kolona sahip.

SQL_HANDLE kolonunda yer alan veriyi, veritabanını bulmak için kullanabiliriz. Yapmamız gereken SYS.DM_EXEC_SQL_TEXT DMF‘i ile CROSS JOIN işlemine tabi tutarak, DBID kolonuna erişmek. Böylece DB_NAME sistem fonksiyonu sayesinde veritabanının ismine ulaşabiliriz.

SELECT
	SUM(EQS.TOTAL_LOGICAL_READS) AS TOPLAM_OKUMA,
	SUM(EQS.TOTAL_LOGICAL_WRITES) AS TOPLAM_YAZMA,
	ISNULL(DB_NAME(EST.DBID), 'AdhocSQL') AS VERITABANI
FROM
	SYS.DM_EXEC_QUERY_STATS AS EQS
	CROSS APPLY SYS.DM_EXEC_SQL_TEXT(EQS.SQL_HANDLE) AS EST
GROUP BY
	DB_NAME(EST.DBID)