Pages

Monday, May 30, 2011

SQL Server : Large Unused Space


To do checking to the size used in a table in SQL Server, you can do this query :
SAMPLE :
EXEC sp_spaceused ssmaddr, 'TRUE'
    note : ssmaddr is the table name
RESULT :
    name       rows   reserved   data      index_size    unused
    ssmaddr    25948  218944 KB  32256 KB  72 KB         186616 KB


SYNTAX :
sp_spaceused [[ @objname= ] 'objname' ] [,[ @updateusage= ] 'updateusage' ]

@objname='objname'
Is the qualified or nonqualified name of the table, indexed view, or queue for which space usage information is requested. Quotation marks are required only if a qualified object name is specified. If a fully qualified object name (including a database name) is provided, the database name must be the name of the current database.
If objname is not specified, results are returned for the whole database.
objname is nvarchar(776), with a default of NULL.
@updateusage='updateusage'
Indicates DBCC UPDATEUSAGE should be run to update space usage information. When objname is not specified, the statement is run on the whole database; otherwise, the statement is run on objname. Values can be true orfalse. updateusage is varchar(5), with a default of false.

Column name
Data type
Description
name
nvarchar(128)
Name of the object for which space usage information was requested.
The schema name of the object is not returned. If the schema name is required, use thesys.dm_db_partition_stats or sys.dm_db_index_physical_stats dynamic management views to obtain equivalent size information.
rows
char(11)
Number of rows existing in the table. If the object specified is a Service Broker queue, this column indicates the number of messages in the queue.
reserved
varchar(18)
Total amount of reserved space for objname.
data
varchar(18)
Total amount of space used by data in objname.
index_size
varchar(18)
Total amount of space used by indexes in objname.
unused
varchar(18)
Total amount of space reserved for objname but not yet used.


Like you can see, that the unused space of the table is 2.311.672 KB, and the data itself is only 524.712 KB.
This usually happened when a table didn't use clustered index.
ANALOGY :
Table is like a book, example : debts table.
There is 5 people that owe you some money, then we will note it down in our book ( in this case, our debts table) :
                Customer            Balance
                A                             1000
                B                             2000
                C                             3000
                D                             4000
                E                             5000
Then Customer A give the moeny back to us, what we do is we delete Customer A from our book (debts table)
                Customer            Balance
                                               
                B                             2000
                C                             3000
                D                             4000
                E                             5000

After that customer F, borrow some money from us, what we do, off course, we note that in our book (debts table)
Now this is the different between clustered index and non-clustered index :
On clustered index :
          Customer            Balance
                F                             6000                      
                B                             2000
                C                             3000
                D                             4000
                E                             5000
In non-clustered index :
          Customer            Balance
                                               
                B                             2000
                C                             3000
                D                             4000
                E                             5000
          F                             6000

As you can see, on non-clustered index, the empty part (row), will not be re-used, but the size will still be there.
On clustered index, the empty part (row), will be re-used

So, the solution is :
SOLUTIONS :
On SQL 2000 before SP4(clustered or non-clustered index), SQL Server 2000 SP 4 and after(non-clustered index):
Copy all the table to temporary table, delete the original table content, then put the content from temporary table, back to original table.


Pada SQL 2000 SP4 & SQL 2005 and after (clustered index) :
SAMPLE :
DBCC DBREINDEX ssmaddr
DBCC INDEXDEFRAG


SYNTAX :
DBCC DBREINDEX ( table_name [ , index_name [ , fillfactor ] ] ) [ WITH NO_INFOMSGS ] 

table_name
Is the name of the table containing the specified index or indexes to rebuild. Table names must follow the rules for identifiers.
index_name
Is the name of the index to rebuild. Index names must comply with the rules for identifiers. If index_name is specified, table_name must be specified. If index_name is not specified or is " ", all indexes for the table are rebuilt.
fillfactor
Is the percentage of space on each index page for storing data when the index is created or rebuilt. fillfactorreplaces the fill factor when the index was created, becoming the new default for the index and for any other nonclustered indexes rebuilt because a clustered index is rebuilt. When fillfactor is 0, DBCC DBREINDEX uses the fill factor value last specified for the index. This value is stored in the sys.indexes catalog view.
If fillfactor is specified, table_name and index_name must be specified. If fillfactor is not specified, the default fill factor, 100, is used. For more information, see Fill Factor.
WITH NO_INFOMSGS
Suppresses all informational messages that have severity levels from 0 through 10.

SYNTAX :
DBCC INDEXDEFRAG  ( { database_name | database_id | 0 }  , { table_name | table_id | 'view_name' | view_id , { index_name | index_id }   )    [ WITH NO_INFOMSGS ]
database_name | database_id | 0
Is the database for which to defragment an index. Database names must conform to the rules for identifiers. For more information, see Using Identifiers. If 0 is specified, then the current database is used.
table_name | table_id | 'view_name' | view_id
Is the table or view for which to defragment an index. Table and view names must conform to the rules for identifiers.
index_name | index_id
Is the index to defragment. Index names must conform to the rules for identifiers.
WITH NO_INFOMSGS
Suppresses all informational messages (with severity levels from 0 through 10).

Result :
Before :
      name       rows   reserved   data      index_size    unused
      ssmaddr    25948  218944 KB  32256 KB  72 KB         186616 KB

After 
name       rows   reserved   data      index_size    unused

ssmaddr    25948  6800 KB    6664 KB   48 KB         88 KB



Reference :
http://msdn.microsoft.com/en-us/library/ms188776.aspx
http://support.microsoft.com/kb/924947
http://msdn.microsoft.com/en-us/library/ms181671.aspx



Thursday, May 19, 2011

Crystal Report - Load Report Failed on ASP.Net Page deployed in IIS 7 - Windows Server 2008 x64

Load Report Failed 
Yesterday i got this error, when i'm trying to load my crystal report in production machine. This one is a generic error, it means that, you maybe wondering where this error come from, even i'm wondering too ^^.
Before, in my development machine, everything is fine, i can see the report. 
When i tried to deploy it in my production machine, suddenly this error show up.


This is what i do to solve this problem :
1. Go to IIS -> Application Pools
2. Right click on DefaultAppPool (or application pools that your site using) --> Choose advanced Settings...
If you are thinking How To : Check Application Pools that a site is using from IIS 7, please click the link
3. Choose identity
4.Choose Network Services
5.Choose Ok and then Ok again


You are ready to go ^^


Off  course there some things that you need to check first, like :
1. Gave full rights for “C:\WINDOWS\Temp” folder depending on IIS user
2. Redistributable crystal version has installed
Reference : Sendy Santoso (http://geekydeveloper.blogspot.com/)

How To : Check Application Pools that a site is using from IIS 7

Check Application Pools
Things that you need to do :
1. Open IIS, in this case IIS 7
2. Go to sites -> Default Web Site -> 'YourSiteName'
3. Go to action panel, choose Advanced Settings...
4. There you will see the name of your application pools 

You are ready to go ^^
Reference : Sendy Santoso (http://geekydeveloper.blogspot.com/)