Kamis, 11 Desember 2008

Gathering I/O statistics down to the SQL Server database file level

Problem
When managing your SQL Server environment there are many aspects that need to be reviewed to determine where the bottlenecks are occurring to ensure you are getting the best performance possible. SQL Server offers many great tools and functions to determine issues with locking, blocking, fragmentation, missing indexes, deadlocks, etc... In addition, to looking at all of these areas another area of concern is I/O. Disk I/O can be tracked at the OS level by using counters in Performance Monitor, but these counters give you an overall picture of what is occurring on the server. What other options are available to look at I/O related information down to the file level for each database?


Solution
As mentioned above, SQL Server offers many great little functions and utility programs to help you gain an insight as to what is occurring on the server. One of these tools is fn_virtualfilestats.

This function, fn_virtualfilestats allows you to get information for each physical file that is being used to hold your data including both the data and log files. The function returns read and write information as well as stall information, which is the time users had to wait for an I/O operation to complete. Each time this function is called it returns the overall numbers that SQL Server has collected since the last time the database engine was started, so to use this effectively you need to gather data from two different points of time and then do a comparison.

To run this function to get data for all databases and all files this can be done as easily as this:

SQL 2005





SELECT * FROM fn_virtualfilestats(NULL,NULL);

SQL 2000




SELECT * FROM :: fn_virtualfilestats(-1, -1)

The output for SQL 2000 and 2005 is pretty much the same, but some additional columns have been added for SQL Server 2005.



Column Name NotesDescription
DbId
Database ID.
FileId
File ID.
TimeStamp
Database timestamp at which the data was taken.
NumberReads
Number of reads issued on the file.
BytesRead
Number of bytes read issued on the file.
IoStallReadMSSQL2005 onlyTotal amount of time, in milliseconds, that users waited for the read I/Os to complete on the file.
NumberWrites
Number of writes made on the file.
BytesWritten
Number of bytes written made on the file.
IoStallWriteMSSQL2005 onlyTotal amount of time, in milliseconds, that users waited for the write I/Os to complete on the file.
IoStallMS
Sum of IoStallReadMS and IoStallWriteMS.
FileHandle
Value of the file handle.
BytesOnDiskSQL2005 onlyPhysical file size (count of bytes) on disk.

For database files, this is the same value as size in sys.database_files, but is expressed in bytes rather than pages.



For database snapshot spare files, this is the space the operating system is using for the file.


(Source SQL Server 2005 Books Online)

Sample Output

As you can see from the sample output, the Dbid and FileId columns are pretty cryptic. The Dbid can be be translated to the database name pretty easily by using the DB_NAME() function, but the fileId needs to be looked up from one of the system tables.

To lookup the filename from the system tables you can use these queries.

SQL 2005




SELECT dbid, fileid, filename
FROM sys.sysaltfiles
WHERE dbid = 5 and fileid in (1,2)

SQL 2000




SELECT dbid, fileid, filename
FROM dbo.sysaltfiles
WHERE dbid = 5 and fileid in (1,2)

Here is sample output.

From just using this function directly you can gather data from two different points in time and then do a comparison to determine the change that has occurred between these two periods of time. Here is a sample query that gathers data, waits for a period of time and then gathers data again to show you a comparison.

This example is written for SQL Server 2005, but can easily be changed for SQL 2000.




USE master
GO

-- create table
IF NOT EXISTS (SELECT *
FROM sys.objects
WHERE OBJECT_ID = OBJECT_ID(N'[dbo].[filestats]')
AND
type IN (N'U'))
BEGIN
CREATE TABLE
filestats
(dbname VARCHAR(128),
fName VARCHAR(2048),
timeStart datetime,
timeEnd datetime,
timeDiff bigint,
readsNum1 bigint,
readsNum2 bigint,
readsBytes1 bigint,
readsBytes2 bigint,
readsIoStall1 bigint,
readsIoStall2 bigint,
writesNum1 bigint,
writesNum2 bigint,
writesBytes1 bigint,
writesBytes2 bigint,
writesIoStall1 bigint,
writesIoStall2 bigint,
ioStall1 bigint,
ioStall2 bigint
)
END

-- clear data
TRUNCATE TABLE dbo.filestats

-- insert first segment counters
INSERT INTO dbo.filestats
(dbname,
fName,
TimeStart,
readsNum1,
readsBytes1,
readsIoStall1,
writesNum1,
writesBytes1,
writesIoStall1,
IoStall1
)
SELECT
DB_NAME(a.dbid) AS Database_name,
b.filename,
GETDATE(),
numberReads,
BytesRead,
IoStallReadMS,
NumberWrites,
BytesWritten,
IoStallWriteMS,
IoStallMS
FROM
fn_virtualfilestats(NULL,NULL) a INNER JOIN
sysaltfiles b ON a.dbid = b.dbid AND a.fileid = b.fileid
ORDER BY
Database_Name

/*Delay second read */
WAITFOR DELAY '000:01:00'

-- add second segment counters
UPDATE dbo.filestats
SET
timeEnd = GETDATE(),
readsNum2 = a.numberReads,
readsBytes2 = a.BytesRead,
readsIoStall2 = a.IoStallReadMS ,
writesNum2 = a.NumberWrites,
writesBytes2 = a.BytesWritten,
writesIoStall2 = a.IoStallWriteMS,
IoStall2 = a.IoStallMS,
timeDiff = DATEDIFF(s,timeStart,GETDATE())
FROM
fn_virtualfilestats(NULL,NULL) a INNER JOIN
sysaltfiles b ON a.dbid = b.dbid AND a.fileid = b.fileid
WHERE
fName= b.filename AND dbname=DB_NAME(a.dbid)

-- select data
SELECT
dbname,
fName,
timeDiff,
readsNum2 - readsNum1 AS readsNumDiff,
readsBytes2 - readsBytes2 AS readsBytesDiff,
readsIoStall2 - readsIOStall1 AS readsIOStallDiff,
writesNum2 - writesNum1 AS writesNumDiff,
writesBytes2 - writesBytes2 AS writesBytesDiff,
writesIoStall2 - writesIOStall1 AS writesIOStallDiff,
ioStall2 - ioStall1 AS ioStallDiff
FROM dbo.filestats

Summary
One problem that you may be faced with though is that not all files are stored on their own physical disks, so you may have a case where you want to look at things from a drive perspective vs. at an individual file level. Here is a previous article written by Andy Novick that has the entire process broken down into functions, so you can aggregate things to a drive perspective. The article can be found here, Examining SQL Server's I/O Statistics

Next Steps

  • When researching performance problems, don't forget to look at I/O stats as well. This handy little function could give you big insight into some of your performance issues.
  • Stay tuned for more performance related tips, but for now check out these other tips





































Sabtu, 25 Oktober 2008

HIDE CAPTION MDIFORM

Menghilangkan Caption dan ControlBox dari Form sangat mudah sekali. Namun untuk menghilangkan Caption dan ControlBox dari MDIForm diperlukan teknik khusus dengan menggunakan Sistem API. Caranya cukup mudah :

Langkah 1 : Buat Project Baru

Langkah 2 : Tambahkan MDI Form, kemudian tambahkan picturebox dan caption diatasnya serta tombol sebagai ganti dari tombol Close. Gambarannya adalah seperti berikut


Langkah 3 : Tuliskan syntax berikut ini

Option Explicit

Private Sub cmdClose_Click()
End
End Sub

Private Sub MDIForm_Load()
HideCaption hWnd, False
End Sub

Langkah 4 : Tambahkan Module dengan syntax berikut ini

Option Explicit

Private Enum WinType
GWL_STYLE = (-16)
SWP_FRAMECHANGED = &H20
SWP_NOMOVE = &H2
SWP_NOZORDER = &H4
SWP_NOSIZE = &H1
End Enum

'-----Function API - Window
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long, ByVal wNewWord As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowPos Lib "user32" _
(ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, _
ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

Public Function HideCaption(hWnd As Long, Optional ShowBorder As Boolean = True)
Dim lStyle As Long
lStyle = GetWindowLong(hWnd, GWL_STYLE)
If ShowBorder Then
lStyle = lStyle Or &HC00000
Else
lStyle = lStyle And Not &HC00000
End If
Call SetWindowLong(hWnd, GWL_STYLE, lStyle)
Call pRedraw(hWnd)
lStyle = GetWindowLong(hWnd, GWL_STYLE)
End Function

Private Sub pRedraw(hWnd As Long)
Const swpFlags As Long = _
SWP_FRAMECHANGED Or SWP_NOMOVE Or _
SWP_NOZORDER Or SWP_NOSIZE
Call SetWindowPos(hWnd, 0, 0, 0, 0, 0, swpFlags)
End Sub

Maka Hasilnya adalah


Manfaat SMS Gateway

SMS Gateway adalah kesatuan perangkat yang minimal terdiri dari sebuah PC dengan modem GSM/CDMA, sebuah kartu GSM/CDMA dengan nomor direct/premium, dan sebuah program aplikasi yang berfungsi untuk mengorganize (menerima atau mengirim) sms. Aplikasi SMS Gateway mampu mengintegrasikan antara teknologi ponsel dengan komputer (PC).

Dengan SMS Gateway ini Anda bisa melakukan beberapa hal secara otomatis seperti misalnya :

  • Mengingatkan anda untuk acara atau meeting penting
  • Mempromosikan berbagai promosi untuk pelanggan-pelanggan
  • Melakukan follow up pada pelanggan
  • Memberikan laporan lengkap dan akurat terhadap semua kegiatan harian
  • Image perusahaan Anda juga meningkat, karena tidak banyak perusahaan yang menyediakan SMS hotline untuk pelanggannya.

Betapa nyamannya jika Anda memiliki Customer Service yang profesional dan setia menangani semua pelanggan Anda setiap saat.

Penerapan SMS Gateway ini dapat digunakan oleh bebagai jenis industri / bisnis, misalnya :

  • Bank : payment, info rekening, transaksi, PLN Online, m-Banking
  • Travel Agent : ticketing, reservations
  • Properti Agent/Developer : promotion, exhibition, sales.
  • Showroom : info new produk, member promotions.
  • Hipermarket/Toko/MLM : produk update, promotions
  • Bengkel : service alerting.
  • Rumah Sakit : jadwal praktek dokter, appointment, registration, antrian pasien, medical status, docter alerting.dll
  • Organisasi Sosial : undangan, jadwal meeting.
  • Klub Golf : reservation.
  • Komunitas : scheduling, appointment.
  • Industri Farmasi/Distribusi : stock, sales, pricelist.
  • Kurir : untuk trakking delivery, track order, customer.
  • Restaurant : untuk deliveri order, promotion.
  • Sistemm ERP : modul tambahan sms.
  • Hotel : reservation, fasilities, Promotions.
  • Airlines : ticket reservation, kru scheduling
  • Theatre : ticket, reservation, kru scheduling, promotion.
  • Importir/Distributor : check stock, pricelist, reseller.
  • Media : Polling, Feed back, Quiz, Promotions.
  • Entertainment : Games, Quiz, Polling, Chatting
  • Politik : Tim Sukses, Quick Count Pilkada,
  • dll

Cetak Printer Stiker

Berikut ini Contoh penggunaan printer Stiker

Nama Printer : Zebra TLP 2844-Z

XA Start Format
XZ End Format
MD Media Darkness
LL Label Length
LH Label Home
FO Font (Posisi awal Kalimat)
AFN Ukuran Font
FD Cetak Data

Source Code :

Open "LPT1:" For Output As #1

'----Start Format----
Print #1, "^XA"
'--------------------
Print #1, "^MD30.1" 'Media Darkness
Print #1, "^LL225" 'Label Length
Print #1, "^LH1,20" 'Label Home
'-------Field--------
Print #1, "^FO100,015" 'Posisi Kalimat Left,Top
Print #1, "^AFN,12,10" 'Font, Height, Width
Print #1, "^FD" + “Nama Barang” + "^FS" 'Cetak Data
‘===>
Print #1, "^FO100,055"
Print #1, "^AFN,12,10"
Print #1, "^FD" + “Keterangan Barang” + "^FS"
'===>
Print #1, "^FO100,085"
Print #1, "^AFN,12,10"
Print #1, "^FD" + “Pabrik Pembuat” + "^FS"
'===> Barcode
Print #1, "^FO600,020"
Print #1, "^BY2^BY2"
Print #1, "^B8N,50,N,N"
Print #1, "^FD" + “Kode Barang” + "^FS"
'----End Format----
Print #1, "^XZ"

Close #1