Staining deck: lessons learned

I cleaned and stained my deck all by myself this summer. The sanding was done last summer, how is that for procrastination! I think I did all right, however there are still a lot of areas for improvements. Hence this note.

  • I used Rymar Xtreme Weather Wood Sealer, 7630 Sienna. My deck needs 4 gallons. My wife ordered 2 gallons initially. I ordered the third one, then had to order one more. It would have been better to have all 4 gallons available. At the time of this writing, if you order more than 1 gallon, shipping is free;
  • I used a deck cleaner. I sprayed it using a small hand-held squirt type sprayer. That wasn’t efficient. I should have used the larger sprayer with a hand pump;
  • To protect plants around deck from deck cleaner, I used plastics I saved from packaging material. It worked fine;
  • For the floor, use a nap roller made out of microfiber, not foamy/spongy stuff. The foamy/spongy roller works better indoors on a smooth surface;
  • To protect the stucco wall, I taped around it. I used two type of 3M tapes: the coarser one seems to work better outdoors. Somebody suggested that FrogTape works better. I think I’ll try it next time. Also, where there is enough space between the deck and the wall, it might be easier and quicker to insert a card board instead of using masking tape;
  • Use drop cloth when I stain poles supporting the tandem room. I didn’t this time and ended up with a few drops on my pavement;
  • I used brush for sticks/pickets/balusters. Next time I may try a small roller, which can make things quicker;
  • Not directly related to staining, but I should have used the right hose for connection to my electric power washer. My hand was greasy and I had trouble taking the head off the good hose, so I used another one. I should have taken the time to get a wrench to get the head off of the good hose and use it instead. The less than optimal hose leaked. I didn’t do as good a job as I could have with the right hose.
  • Don’t paint myself into a corner. It didn’t happen to me, but it’s always to keep this in mind.
  • Wear protective gloves. I didn’t for a short stretch, and got splinter in my middle finger. That wasn’t fun!

Index compression script generation

I wrote a script to generate script for non-clustered index page compression in SQL Server. I’ve since made improvements and here it is.

Highlights:

  • This script generates index compression script on a partition by partition basis, if the underlying index is partitioned;
  • Like the previous version, it still works for non-partitioned indexes;
  • Like the previous version, it compresses indexes from smallest to largest, progressively saving space as it nibbles forward. Therefore it is unlikely that it’ll grow data file(s) during rebuild;
  • Unlike the previous version, I’ve set maxdop = 0, which let’s SQL decides degree of parallelism;
  • There is no quick way, that I know of, to tell if an underlying index is partitioned. Hence the usage of two temp tables to differentiate the two for proper script generation.
IF Object_id('tempdb..#NonPartitionedIndex') IS NOT NULL 
  DROP TABLE #nonpartitionedindex 

SELECT object_id, 
       index_id 
INTO   #nonpartitionedindex 
FROM   sys.partitions 
WHERE  object_id > 255 
       AND data_compression IN ( 0, 1 ) -- Non-compressed 
       AND index_id > 1 
GROUP  BY object_id, 
          index_id 
HAVING Count(*) = 1 

IF Object_id('tempdb..#PartitionedIndex') IS NOT NULL 
  DROP TABLE #partitionedindex 

SELECT object_id, 
       index_id 
INTO   #partitionedindex 
FROM   sys.partitions 
WHERE  object_id > 255 
       AND data_compression IN ( 0, 1 ) -- Non-compressed 
       AND index_id > 1 
GROUP  BY object_id, 
          index_id 
HAVING Count(*) > 1 

SELECT s.NAME 
       AS 
       SchemaName, 
       t.NAME 
       AS TableName, 
       i.NAME 
       AS IndexName, 
       'ALTER INDEX ' + i.NAME + ' ON ' + s.NAME + '.' 
       + t.NAME 
       + 
' REBUILD WITH (SORT_IN_TEMPDB = ON, MAXDOP = 0, DATA_COMPRESSION = PAGE);' AS 
       AlterRebuild, 
       Sum(a.total_pages) * 8 
       AS TotalSpaceKB, 
       Sum(a.used_pages) * 8 
       AS UsedSpaceKB, 
       ( Sum(a.total_pages) - Sum(a.used_pages) ) * 8 
       AS UnusedSpaceKB
FROM   sys.tables t 
       JOIN sys.schemas s 
         ON s.schema_id = t.schema_id 
       JOIN sys.indexes i 
         ON t.object_id = i.object_id 
       JOIN sys.partitions p 
         ON i.object_id = p.object_id 
            AND i.index_id = p.index_id 
       JOIN sys.allocation_units a 
         ON p.partition_id = a.container_id 
       JOIN #nonpartitionedindex npi 
         ON p.object_id = npi.object_id 
            AND p.index_id = npi.index_id 
WHERE  i.index_id > 1 -- Non-clustered indexes  
       AND p.data_compression IN ( 0, 1 ) -- Non-compressed  
       AND t.NAME <> 'dtproperties' -- Ignore certain tables  
       AND t.is_ms_shipped = 0 
       AND i.object_id > 255 -- Non-system objects  
GROUP  BY s.NAME, 
          t.NAME, 
          i.NAME, 
          p.partition_number 
UNION ALL 
SELECT s.NAME                                         AS SchemaName, 
       t.NAME                                         AS TableName, 
       i.NAME                                         AS IndexName, 
       'ALTER INDEX ' + i.NAME + ' ON ' + s.NAME + '.' 
       + t.NAME 
       + 
' REBUILD WITH (SORT_IN_TEMPDB = ON, MAXDOP = 0, DATA_COMPRESSION = PAGE ON PARTITIONS (' 
+ Cast(p.partition_number AS VARCHAR(3)) 
+ '));'                                        AS AlterRebuild, 
Sum(a.total_pages) * 8                         AS TotalSpaceKB, 
Sum(a.used_pages) * 8                          AS UsedSpaceKB, 
( Sum(a.total_pages) - Sum(a.used_pages) ) * 8 AS UnusedSpaceKB
FROM   sys.tables t 
       JOIN sys.schemas s 
         ON s.schema_id = t.schema_id 
       JOIN sys.indexes i 
         ON t.object_id = i.object_id 
       JOIN sys.partitions p 
         ON i.object_id = p.object_id 
            AND i.index_id = p.index_id 
       JOIN sys.allocation_units a 
         ON p.partition_id = a.container_id 
       JOIN #partitionedindex pi 
         ON p.object_id = pi.object_id 
            AND p.index_id = pi.index_id 
WHERE  i.index_id > 1 -- Non-clustered indexes  
       AND p.data_compression IN ( 0, 1 ) -- Non-compressed  
       AND t.NAME <> 'dtproperties' -- Ignore certain tables  
       AND t.is_ms_shipped = 0 
       AND i.object_id > 255 -- Non-system objects  
GROUP  BY s.NAME, 
          t.NAME, 
          i.NAME, 
          p.partition_number 
ORDER  BY UsedSpaceKB

PASS 2012 impressions

This is my first PASS conference after a few years of absence. A few thoughts and impressions:

1. It was good catching up with a few friends. There are still a few old friends I missed, and a few that I really would have liked to talk longer.

2. Microsoft’s Hekaton announcement is interesting. A few years back I saw VoltDB demos and that was impressive. Microsoft’s announcement will accelerate in-memory transactional database developement and help bring this technology to a wider audience.

3. Solid state disks see more adaption but they are still pretty expensive. Hopefully its wider adaption will help to drive the cost down as time goes on. There are a few vendors that uses some creative ways to squeeze the most out of the investment by pairing mechenical disks with solid state disks, such as algo-based data movement: when it detects some data on spindle disks are “hot”, it moves them to solid state disks. That sounds interesting if done well.

4. It was really nice meeting a number of Chinese-speaking attendees. Great networking and fun discussions!

5. The mojito and bloody mary from Edge Grille is not very good in my opinion. Beer from Gordon Biersch is ordinary, nothing to write home about, ymmv.

Come and join the Oak Park IT Group

Here is the URL for the impatient: http://www.meetup.com/The-Oak-Park-IT-group/ The group is free to join.

I like user groups. Over the years, I’ve been to SQL Server, MySQL, and Linux user group meetings, learned and shared with my colleagues. The quality of the meetings fluctuates and I like some sessions better than others. However, after a hard day’s work, going out of one’s way to attend a meeting that may or may not be productive can be a turn off, especially for married person(s) with child(ren) at home. So I attempted to start a local MySQL group a few years ago, but it never took off, mostly due to lack of time and effort, I think.

I am giving this another shot. The ideas I wrote before are still valid, so I quote some here:

When I think a user group, I think about fans getting together hacking stuff: demonstrating cool tips and techniques, dissecting a new technology such as MySQL proxy by a user who have done that and learned some hard lessons along the way with no marketing talk, discussing solutions to problems a user has, providing pointers and efficient scripts, etc. In such a setting, each member of the group takes turns providing his/her expertise.

The presenter does not necessarily need talking slides, but must prepare beforehand about the topic s/he will present. The key points for a night’s session can be distilled into a few points on an index card, and demonstrated with simple, and hopefully elegant steps. I’ve watched so many demos that needs elaborate setup, that by the time of the supposed highlight the audience have already tuned out or lost interest. When a question arises that can be answered via live demo in a short time, answer the question that way, instead of just giving an verbal response.

I deliberately made this a broader interest group, to avoid opinionated fan boys. I like MySQL and SQL Server, and want to expand the depth and breadth of my knowledge in those areas, but that does not prevent me from wanting to learn more about Oracle and PostgreSQL. I deal with relational data most of the time, but I have a keen interest in learning more about Hadoop, column-based database engines, and analytical databases. I am in database administration field, but I want to know more about networking, TCP/IP, Active Directory and LDAP. I maintain my own web site and wiki, but want to lean more about Tengine, Nginx. You get the idea. Hence the broad IT umbrella is by design.

A few pointers come to mind for future members:

1. Be open and respectful to others;
2. Be willing to share. We all are specialist in certain areas;
3. No hidden agenda. Networking and building up informal friendships/relationships is not hidden agenda, but peddling and proselytizing is. One is obviously free to introduce services and products, but that can only happen AFTER one contributes something meaningful to the group, and does so in a frequency that does not annoy other members.
4. I welcome sponsorship to cover Meetup registration fees, possible meeting room renting fees, refreshments, as necessary. I paid 72 bucks to register this group for 6 months at meetup.com. Renting a discussion room in the local Oak Park library that houses 40 people costs 20 bucks for 4 hours, although I doubt we need that, at least not initially. I think using a study room in the library, free of charge, will be the way to go in the beginning. Or we can meet in a coffee house. We’d like to pass out sponsor’s printed fliers and give the main sponsor 5 minutes (strictly timed) of our time.

I welcome presentations from vendors, but they should be technical and practical, with minimal amount of fluff and marketing material.

So, if you live around Oak Park, River Forest, Elmwood Park, Berwyn, Maywood, Forest Park, Melrose Park and other surrounding areas, and are interested in IT, come join us. I will work out an event schedule as soon as there is one more person joining the group. Currently there are two persons, including me.

Déjà vu

As I was commenting on a friend’s blog, I reviewed Obama’s victory speech in 2008, and realized, at least to my mind, an ironic déjà vu.

Not too long into His Majesty Bush The Second’s reign, right after 9/11, we had the world rally around us. Along with the tremendous good will came the potential to bring enormous positive impact to the world, had we used restraint and followed the rule of law to bring the perpetrators to justice. We all knew how that was not so, and how we followed a reactionary, criminal, xenophobic, and imperialistic path externally. And the destructive, criminal, too-big-to-fail-eventually-bailed-out financial industry and big investment banks armed with fancy math derivatives and high-powered computers trashed our already weak economy internally. And get this, His Majesty Bush The Second got RE-ELECTED in the midst of all this. Yay American democracy!

The Bush dynasty was finally over, for now. Along came The Saviour, The Chosen One, with remarkable oratory skills and seemingly radiating transcending, above-the-fray power. After reading his excellent book “Dreams from My Father” (highly recommended still, even with my total disillusion of Obama today) and his so-so “The Audacity of Hope”, and his campaign promises at the time, I enthusiastically canvassed for him, knocking doors, and cast my first general election presidential ballot as an American to the Democrats.

Now HOPE is here. Once again the world rallied around us. In fact, the bunch of increasingly irrelevant Norwegian old men awarded him the Peace Prize simply because he is not Bush. (Granted, I don’t want to discount the significance of our first black/inter-racial president.) Once again, like Bush, Obama could have used the tremendous good will to do enormous good to America and the world.

Look at what happened. Glenn Greenwald says the best here in an editorial he wrote for the Guardian. So I will just quote him here:

Therein lies one of the most enduring attributes of Obama’s legacy: in many crucial areas, he has done more to subvert and weaken the left’s political agenda than a GOP president could have dreamed of achieving. So potent, so overarching, are tribal loyalties in American politics that partisans will support, or at least tolerate, any and all policies their party’s leader endorses – even if those policies are ones they long claimed to loathe.

This dynamic has repeatedly emerged in numerous contexts. Obama has continued Bush/Cheney terrorism policies – once viciously denounced by Democrats – of indefinite detention, renditions, secret prisons by proxy, and sweeping secrecy doctrines.

He has gone further than his predecessor by waging an unprecedented war on whistleblowers, seizing the power to assassinate U.S. citizens without due process far from any battlefield, massively escalating drone attacks in multiple nations, and asserting the authority to unilaterally prosecute a war (in Libya) even in defiance of a Congressional vote against authorising the war.

Domestically, Obama kept the insiders and Goldman-Sachs in charge of our financial industry, as per our tradition in the last several decades. And the economy is still in disarray.

So there you go. That is Déjà vu in my dictionary. This coming general election, I will show up, but I won’t cast my ballot to any candidate.

I won’t allow comment for this one. I’ve got plenty to do!