Tag: syndicated

  • Common SQL Server Mistakes – SELECT *

    I’ve been trying to work on some new presentations so that I have a variety, including some spares, when I go to events. One of the topics that I think has some value, especially for .NET and sysadmin groups, is a list of common mistakes, how to fix them, and why they’re bad.
    I was going to call this Common Developer Mistakes, but I’m not sure that would go over well at Developer events, and I see DBAs making these mistakes along with Windows admins.
    I decided to build a series of blog posts as I work through the presentation to document some of the issues, and help me work through speaking points. Please feel free to comment.
    SELECT * Is For Short Term Use Only
    The first mistake that I often see in application code is that too often people write things like

    SELECT * 
    FROM Sales.Customer

    .csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, “Courier New”, courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }

    What does this do? If I run this in my 2008 AdventureWorks database, I get something like this:

     SelectStar_b

    You can see that I end up with multiple columns (CustomerID, TerritoryID, CustomerType, rowguid, ModifiedDate). That’s handy, and cool, and allows me to get all the data in the table.

    But do I really need it?

    In most applications, my guess is that we don’t. Why do we need TerritoryID? That’s a foreign key to the SalesTerritory table, and typically what I want instead is the SalesTerritory.Name column instead of the ID value.

    I could do this:

    SELECT *
    FROM Sales.Customer c
    INNER JOIN Sales.SalesTerritory t
    ON c.TerritoryID = t.TerritoryID

    but that’s any better. Now I’ve returned even more columns, 10 more to be exact, including TerritoryID twice, once from each table. In AdventureWorks, this is 19k rows, and at a minimum this query has returned 19k rows x 8 bytes (int data type) too much data. That doesn’t sound like a lot, but what if this runs in your application 500 times a day? That’s a lot of wasted:

    • bandwidth
    • disk access
    • memory from caching
    • CPU work on the server AND client

    I would also guess that most of the time when you access a customer, you don’t even want all the rows. Likely you want to filter this somehow, and you will with a WHERE clause, but it’s still wasted time and resources.

    We know that the database often is a bottleneck. It’s a shared resource, it’s one machine, and it doesn’t scale as easy as multiple clients or web servers, or even developers, so we should avoid wasting resources when we don’t have to.

    What Do You Do?

    Here’s what I recommend:

    You can write this, and it’s what I often do:

    SELECT TOP 2
    *
    FROM Sales.Customer

    And I get a limited result set:

    SelectStar_e

    Why is this better? I do this so I can easily see the column names. I can then include those in my SELECT statement, with a quick rewrite.

    SelectStar_f

    I could also quickly use the Object Explorer to find the columns like this:

    SelectStar_g

    And you can right click, and choose “script” and “as SELECT”

    SelectStar_h

    and paste the code into your query window. The results would look something like this:

    SelectStar_i

    Alternatively, my employer, Red Gate Software, makes a fantastic product called SQL Prompt that will help you quickly grab columns. For me, I can do an SSF, and get a SELECT * FROM and then choose the table:

    SelectStar_c

    Not that I see the columns to the right. I could also just select the table with a tab and then if I remove my askterisk, I get a list of columns I can easily pick:

    SelectStar_d

    SQL Prompt makes this easier, but it isn’t that hard to just do this by hand. You could easily grab the columns you need from SSMS and add them to queries.

    The database is a limited resource, even if you have a 256 core server with 1024GB of RAM. You still want to query the data you need and only return what’s necessary. A little more effort when building code will pay off later with much better performing applications.

    References
    A few links from other people that see this as an issue as well.

  • Does Join Order Matter?

    According to Conor Cunningham, it doesn’t.

    I have heard that there are issues in the optimizer, and to be sure, there are cases where the order can matter, but for most normal queries, most inner joins, order doesn’t matter. As Conor says, it might seem that a change produces a new plan or changes the performance, but don’t assume that this correlation implies causality.

  • NetFlix and Null

    There are some progressive companies out there, and I think they are doing some very interesting things with how they treat employees and work with them. One thing that Netflix does, and I’ve seen others do, is eliminate the tracking of vacation time. They hold people responsible for getting work done, and if you don’t do the work, you get to move on to another place of employment.

    That got me thinking after following the debate about logic, mathematics and NULL in the SQLServerCentral forums. It’s a fascinating view in how some people look at NULL in databases, and worth reading.

    I started to wonder what the proper value would be for these fields?

    • Netflix.VacationHoursAccrued
    • Netflix.VacationHoursUsed

    Would you set them to 0? Or inifinity, maybe marked by something like 99999?

    Or would you use NULL? With the idea that you don’t know, and more importantly to me, you don’t care? I think that the proper design would depend on what you plan to do with the data. It’s not being used, so my opinion is that NULL works fine, and the NULL bitmap could potentially use less space.

  • Connectify

    It’s a wired world. You’d think by this point, most major hotels, at least those costing upwards of $100/night, would have good wired, or wireless connections for their guests. I’d like it to be free, but I’d settle for good quality.
    However I hate the way that most hotels manage connectivity. It’s not by the connection, or room, but often by the MAC. So that people with one device are fine, but those of us that are techies, with more than one device, can’t connect them all. At least not cheaply.
    connectify[1]
    I usually carry two laptops, a iPhone, and sometimes my wife’s got a laptop and phone as well. I’ve debated carrying a router and using that, but it’s one more thing to carry. Instead I decided to try Connectify.
    It’s a wireless hotspot that runs on Windows 7 and allows your laptop to share it’s connection. You install it, no reboot needed, and then you create a hotspot name and password.
    That’s it.
    Once it’s up and running, in a few minutes, your other devices can connect to your personal hotspot. You have a local LAN and you can easily share files and access the Internet from all your devices.
    A very cool tool. I have it on both of my Win7 laptops to run hotspots, separate names, so whichever one is connected can be my router and allow me high speed access for all my devices on one connection.
    If my Internet connection works in the hotel.