Search Results

Search found 31774 results on 1271 pages for 'chris go'.

Page 172/1271 | < Previous Page | 168 169 170 171 172 173 174 175 176 177 178 179  | Next Page >

  • Validate NSString

    - by Chris
    I am validating an NSString to ensure that the string does not contain apostrophes. The code I'm using to do this is NSCharacterSet * invalidNumberSet = [NSCharacterSet characterSetWithCharactersInString:@"'"]; NSScanner * scanner = [NSScanner scannerWithString:string]; NSString * scannerResult; [scanner setCharactersToBeSkipped:nil]; [scanner scanUpToCharactersFromSet:invalidNumberSet intoString:&scannerResult]; if(![string isEqualToString:scannerResult]) { return 2; } Returning 2 represents an error. This code works, except for the case where the string is an apostrophe. To get around this issue, I added the following code above the preceding block. if([string isEqualToString:@"'"]); { return 2; } This code is evaluating to true, regardless of the input. I need to either prevent the first block from crashing with the input of ', or get the second block to work. What am I missing?

    Read the article

  • Using jquery, what is the simplest function to post some json data and process a returned json respo

    - by Chris Boesch
    When users click on an element in my webpage, I would like to call a javascript function that reads the values of a few text boxes on the page, wraps their contents as json where the keys are the ids for the text boxes and the values are the contents of each text box, and then posts the resulting json to a url. I would then like the same function to expect back a json response and call another javascript function with the returned json data. Question: What is the best way to write the javascript function to create a json structure from html elements, post the json with jquery, and call another javascript function with the resulting json response from the server?

    Read the article

  • What kind of database to use in C#

    - by Chris
    I'm writing a program in C# that will need to store a few Data Tables on the user's computer and load them back when he restarts the program: Up to about 10000 records consisting of text and integers. I don't want to use a CSV file, and I had some trouble with SQLite. Are there any other good options to try?

    Read the article

  • How to create HTML tables from MySQL?

    - by Chris
    Hi Guys, I'm building a part of a system where the user can define "views" from a mysql database. I want some way of generating simple HTML tables/reports from the data, but not just plain output of sql queries- simple joins probably isn't enough. Any ideas?

    Read the article

  • How can I write my code to attempt a database action but continue executing code on failure?

    - by Chris
    Simple question I guess, I want to use PHP to write an update to an existing row in my database, if it doesn't happen I want to log the failure but continue executing the code. While it would be nice to have records of failures to track down issues, that the update failed isn't that important to my user, nor will it affect the running of any other code; the query is simply for a 'cosmetic' but entirely unnecessary piece of information. My database class's query function is set to die on failure, could I modify that or is there another way of doing it without altering my standard query code?

    Read the article

  • Is there a way to update the height of a single UITableViewCell, without recalculating the height for every cell?

    - by Chris Vasselli
    I have a UITableView with a few different sections. One section contains cells that will resize as a user types text into a UITextView. Another section contains cells that render HTML content, for which calculating the height is relatively expensive. Right now when the user types into the UITextView, in order to get the table view to update the height of the cell, I call [self.tableView beginUpdates]; [self.tableView endUpdates]; However, this causes the table to recalculate the height of every cell in the table, when I really only need to update the single cell that was typed into. Not only that, but instead of recalculating the estimated height using tableView:estimatedHeightForRowAtIndexPath:, it calls tableView:heightForRowAtIndexPath: for every cell, even those not being displayed. Is there any way to ask the table view to update just the height of a single cell, without doing all of this unnecessary work? Update I'm still looking for a solution to this. As suggested, I've tried using reloadRowsAtIndexPaths:, but it doesn't look like this will work. Calling reloadRowsAtIndexPaths: with even a single row will still cause heightForRowAtIndexPath: to be called for every row, even though cellForRowAtIndexPath: will only be called for the row you requested. In fact, it looks like any time a row is inserted, deleted, or reloaded, heightForRowAtIndexPath: is called for every row in the table cell. I've also tried putting code in willDisplayCell:forRowAtIndexPath: to calculate the height just before a cell is going to appear. In order for this to work, I would need to force the table view to re-request the height for the row after I do the calculation. Unfortunately, calling [self.tableView beginUpdates]; [self.tableView endUpdates]; from willDisplayCell:forRowAtIndexPath: causes an index out of bounds exception deep in UITableView's internal code. I guess they don't expect us to do this. I can't help but feel like it's a bug in the SDK that in response to [self.tableView endUpdates] it doesn't call estimatedHeightForRowAtIndexPath: for cells that aren't visible, but I'm still trying to find some kind of workaround. Any help is appreciated.

    Read the article

  • Setting language/culture for reporting services report rendered through C#

    - by Chris Latta
    I have written a report renderer in C# that runs and attaches reports to an email. This is all working great, except the date format of the parameters are incorrect when listed in the report title. All the reports have their language set to =User!Language and the parameters are output using the FormatDateTime function to format according to the user's regional settings. I am basically using the rendering method described here on MSDN. This all works great when the reports are run through the browser. However, when I render the report from C# it uses en-US date format. The report server's regional settings are set appropriately to the correct region as are the regional settings of the computer the C# progam is running on.. What property do I need to set in my C# program for the report to be rendered using my appropriate language/culture?

    Read the article

  • Missing } in XML expression

    - by Chris
    I have an external javascript file that I want to, upon include, write some HTML to the end of the web page. Upon doing so though I get the error Missing } in XML expression on the line that uses dropdownhtml. Here is my code var dropdownhtml = '<div id="dropdown"></div>'; $(document).ready(function(){ //$(document).append(dropdownhtml); alert(dropdownhtml); }); The XHTML webpage that includes this file does so like this: <script type="text/javascript" src="/web/resources/js/dropdownmenu.js"></script> Doing either append or alert throws up the same error, what is going wrong?

    Read the article

  • What kind of database to use in .NET

    - by Chris
    I'm writing a program in C# that will need to store a few Data Tables on the user's computer and load them back when he restarts the program: Up to about 10000 records consisting of text and integers. I don't want to use a CSV file, and I had some trouble with SQLite. Are there any other good options to try?

    Read the article

  • Missing } in XML expression

    - by Chris
    I have an external javascript file that I want to, upon include, write some HTML to the end of the web page. Upon doing so though I get the error Missing } in XML expression on the line that uses dropdownhtml. Here is my code var dropdownhtml = '<div id="dropdown"></div>'; $(document).ready(function(){ //$(document).append(dropdownhtml); alert(dropdownhtml); }); Doing either append or alert throws up the same error, what is going wrong?

    Read the article

  • Python if statement not working as expected

    - by Chris Esposito
    I'm searching for a string in a website and checking to see if the location of this string is in the expected location. I know the string starts at the 182nd character, and if I print temp it will even tell me that it is 182, however, the if statement says 182 is not 182. Some code f = urllib.urlopen(link) #store page contents in 's' s = f.read() f.close() temp = s.find('lettersandnumbers') if (htmlsize == "197"): #if ((s.find('lettersandnumbers')) == "182"): if (temp=="182"): print "Glorious" doStuff() else: print "HTML not correct. Aborting." else: print htmlsize print "File size is incorrect. Aborting."

    Read the article

  • [gtk+] error: undeclared function

    - by sterh
    Hello, In my gtk+ application i have function in mainwin.c: void on_prev( GtkWidget* btn, MainWin* mw ) { ... } And in file ui.h i have: #include "mainwin.h" static const GtkActionEntry entries[] = { { "Go Back", GTK_STOCK_GO_BACK, "Go Back", "<control>b", "Go Back", G_CALLBACK(on_prev) }, } But when i try to compile this application, i see error: ui.h:error: 'on_prev' undeclared here (not in a function). What's wrong? Thank you.

    Read the article

  • LINQ Many to Many With In or Contains Clause (and a twist)

    - by Chris
    I have a many to many table structure called PropertyPets. It contains a dual primary key consisting of a PropertyID (from a Property table) and one or more PetIDs (from a Pet table). Next I have a search screen where people can multiple select pets from a jquery multiple select dropdown. Let's say somebody selects Dogs and Cats. Now, I want to be able to return all properties that contain BOTH dogs and cats in the many to many table, PropertyPets. I'm trying to do this with Linq to Sql. I've looked at the Contains clause, but it doesn't seem to work for my requirement: var result = properties.Where(p => search.PetType.Contains(p.PropertyPets)); Here, search.PetType is an int[] array of the Id's for Dog and Cat (which were selected in the multiple select drop down). The problem is first, Contains requires a string not an IEnumerable of type PropertyPet. And second, I need to find the properties that have BOTH dogs and cats and not just simply containing one or the other. Thank you for any pointers.

    Read the article

  • Query to select from two different tables

    - by ryan
    I would like to select from two tables and display my result using this query: CREATE TABLE Buy_Table ( buy_id int identity primary key, user_id int, amount decimal (18,2) ); go INSERT INTO Buy_Table (user_id, amount) VALUES ('1', 10), ('1', 8), ('1', 20), ('3', 1), ('2', 2); go CREATE TABLE Sell_Table ( sell_id int identity primary key, user_id int, amount decimal (18,2) ); go INSERT INTO Sell_Table (user_id, amount) VALUES ('1', 10), ('1', 8), ('1', 20), ('3', 3), ('2', 3); go select [user_id], 'Buy' as [Type], buy_id as [ID], amount from Buy_Table union all select [user_id], 'Sell', sell_id, amount from Sell_Table order by [user_id], [ID], [Type] However the above query will return each row of the user_id like this I want to display my result to something like this in a grid: Can this be done in query itself rather manipulating the grid? Thx

    Read the article

  • jQuery .click() not binding properly

    - by Chris
    I want to perform some action when a link is clicked, I am using the following code to achieve this however it rarely works. If I click the link it usually refreshes the page, and 1/10 times it'll actually pop up "Hi". What is wrong? $(document).ready(function() { $('#slconfiglink').click(function() { alert("hi"); return false; }); }); HTML: <ul> <li><a href="" id="slconfiglink">Config 1</a></li> </ul>

    Read the article

  • Storing an Image with php?

    - by Chris
    I'm trying to store an Image in my website so I can use it easily but I found this php code from here and I can't quite make much sense of it.. I'm just starting php and I dont quite know what to change and what to keep.. I'd greatly appreciate it if you could explain this a little better for me, thanks. <?php $allowedExts = array("jpg", "jpeg", "gif", "png"); $extension = end(explode(".", $_FILES["file"]["name"])); if ((($_FILES["file"]["type"] == "image/gif") || ($_FILES["file"]["type"] == "image/jpeg") || ($_FILES["file"]["type"] == "image/png") || ($_FILES["file"]["type"] == "image/pjpeg")) && ($_FILES["file"]["size"] < 20000) && in_array($extension, $allowedExts)) { if ($_FILES["file"]["error"] > 0) { echo "Return Code: " . $_FILES["file"]["error"] . "<br />"; } else { echo "Upload: " . $_FILES["file"]["name"] . "<br />"; echo "Type: " . $_FILES["file"]["type"] . "<br />"; echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />"; echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />"; if (file_exists("upload/" . $_FILES["file"]["name"])) { echo $_FILES["file"]["name"] . " already exists. "; } else { move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]); echo "Stored in: " . "upload/" . $_FILES["file"]["name"]; } } } else { echo "Invalid file"; } ?>

    Read the article

  • % operator for time calculation

    - by Chris
    I am trying to display minutes and seconds based on a number of seconds. I have: float seconds = 200; float mins = seconds / 60.0; float sec = mins % 60.0; [timeIndexLabel setText:[NSString stringWithFormat:@"%.2f , %.2f", mins,seconds]]; But I get an error: invalid operands of types 'float' and 'double' to binary 'operator%' And I don't understand why... Can someone throw me a bone!?

    Read the article

  • 100% Min Height CSS layout

    - by Chris Porter
    What's the best way to make an element of 100% minimum height across a wide range of browsers ? In particular if you have a layout with a header and footer of fixed height how do you make the middle content part fill 100% of the space in between with the footer fixed to the bottom ?

    Read the article

  • Azure Grid Computing - Worker Roles as HPC Compute Nodes

    - by JoshReuben
    Overview ·        With HPC 2008 R2 SP1 You can add Azure worker roles as compute nodes in a local Windows HPC Server cluster. ·        The subscription for Windows Azure like any other Azure Service - charged for the time that the role instances are available, as well as for the compute and storage services that are used on the nodes. ·        Win-Win ? - Azure charges the computer hour cost (according to vm size) amortized over a month – so you save on purchasing compute node hardware. Microsoft wins because you need to purchase HPC to have a local head node for managing this compute cluster grid distributed in the cloud. ·        Blob storage is used to hold input & output files of each job. I can see how Parametric Sweep HPC jobs can be supported (where the same job is run multiple times on each node against different input units), but not MPI.NET (where different HPC Job instances function as coordinated agents and conduct master-slave inter-process communication), unless Azure is somehow tunneling MPI communication through inter-WorkerRole Azure Queues. ·        this is not the end of the story for Azure Grid Computing. If MS requires you to purchase a local HPC license (and administrate it), what's to stop a 3rd party from doing this and encapsulating exposing HPC WCF Broker Service to you for managing compute nodes? If MS doesn’t  provide head node as a service, someone else will! Process ·        requires creation of a worker node template that specifies a connection to an existing subscription for Windows Azure + an availability policy for the worker nodes. ·        After worker nodes are added to the cluster, you can start them, which provisions the Windows Azure role instances, and then bring them online to run HPC cluster jobs. ·        A Windows Azure worker role instance runs a HPC compatible Azure guest operating system which runs on the VMs that host your service. The guest operating system is updated monthly. You can choose to upgrade the guest OS for your service automatically each time an update is released - All role instances defined by your service will run on the guest operating system version that you specify. see Windows Azure Guest OS Releases and SDK Compatibility Matrix (http://go.microsoft.com/fwlink/?LinkId=190549). ·        use the hpcpack command to upload file packages and install files to run on the worker nodes. see hpcpack (http://go.microsoft.com/fwlink/?LinkID=205514). Requirements ·        assuming you have an azure subscription account and the HPC head node installed and configured. ·        Install HPC Pack 2008 R2 SP 1 -  see Microsoft HPC Pack 2008 R2 Service Pack 1 Release Notes (http://go.microsoft.com/fwlink/?LinkID=202812). ·        Configure the head node to connect to the Internet - connectivity is provided by the connection of the head node to the enterprise network. You may need to configure a proxy client on the head node. Any cluster network topology (1-5) is supported). ·        Configure the firewall - allow outbound TCP traffic on the following ports: 80,       443, 5901, 5902, 7998, 7999 ·        Note: HPC Server  uses Admin Mode (Elevated Privileges) in Windows Azure to give the service administrator of the subscription the necessary privileges to initialize HPC cluster services on the worker nodes. ·        Obtain a Windows Azure subscription certificate - the Windows Azure subscription must be configured with a public subscription (API) certificate -a valid X.509 certificate with a key size of at least 2048 bits. Generate a self-sign certificate & upload a .cer file to the Windows Azure Portal Account page > Manage my API Certificates link. see Using the Windows Azure Service Management API (http://go.microsoft.com/fwlink/?LinkId=205526). ·        import the certificate with an associated private key on the HPC cluster head node - into the trusted root store of the local computer account. Obtain Windows Azure Connection Information for HPC Server ·        required for each worker node template ·        copy from azure portal - Get from: navigation pane > Hosted Services > Storage Accounts & CDN ·        Subscription ID - a 32-char hex string in the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. In Properties pane. ·        Subscription certificate thumbprint - a 40-char hex string (you need to remove spaces). In Management Certificates > Properties pane. ·        Service name - the value of <ServiceName> configured in the public URL of the service (http://<ServiceName>.cloudapp.net). In Hosted Services > Properties pane. ·        Blob Storage account name - the value of <StorageAccountName> configured in the public URL of the account (http://<StorageAccountName>.blob.core.windows.net). In Storage Accounts > Properties pane. Import the Azure Subscription Certificate on the HPC Head Node ·        enable the services for Windows HPC Server  to authenticate properly with the Windows Azure subscription. ·        use the Certificates MMC snap-in to import the certificate to the Trusted Root Certification Authorities store of the local computer account. The certificate must be in PFX format (.pfx or .p12 file) with a private key that is protected by a password. ·        see Certificates (http://go.microsoft.com/fwlink/?LinkId=163918). ·        To open the certificates snapin: Run > mmc. File > Add/Remove Snap-in > certificates > Computer account > Local Computer ·        To import the certificate via wizard - Certificates > Trusted Root Certification Authorities > Certificates > All Tasks > Import ·        After the certificate is imported, it appears in the details pane in the Certificates snap-in. You can open the certificate to check its status. Configure a Proxy Client on the HPC Head Node ·        the following Windows HPC Server services must be able to communicate over the Internet (through the firewall) with the services for Windows Azure: HPCManagement, HPCScheduler, HPCBrokerWorker. ·        Create a Windows Azure Worker Node Template ·        Edit HPC node templates in HPC Node Template Editor. ·        Specify: 1) Windows Azure subscription connection info (unique service name) for adding a set of worker nodes to the cluster + 2)worker node availability policy – rules for deploying / removing worker role instances in Windows Azure o   HPC Cluster Manager > Configuration > Navigation Pane > Node Templates > Actions pane > New à Create Node Template Wizard or Edit à Node Template Editor o   Choose Node Template Type page - Windows Azure worker node template o   Specify Template Name page – template name & description o   Provide Connection Information page – Azure Subscription ID (text) & Subscription certificate (browse) o   Provide Service Information page - Azure service name + blob storage account name (optionally click Retrieve Connection Information to get list of available from azure – possible LRT). o   Configure Azure Availability Policy page - how Windows Azure worker nodes start / stop (online / offline the worker role instance -  add / remove) – manual / automatic o   for automatic - In the Configure Windows Azure Worker Availability Policy dialog -select days and hours for worker nodes to start / stop. ·        To validate the Windows Azure connection information, on the template's Connection Information tab > Validate connection information. ·        You can upload a file package to the storage account that is specified in the template - eg upload application or service files that will run on the worker nodes. see hpcpack (http://go.microsoft.com/fwlink/?LinkID=205514). Add Azure Worker Nodes to the HPC Cluster ·        Use the Add Node Wizard – specify: 1) the worker node template, 2) The number of worker nodes   (within the quota of role instances in the azure subscription), and 3)           The VM size of the worker nodes : ExtraSmall, Small, Medium, Large, or ExtraLarge.  ·        to add worker nodes of different sizes, must run the Add Node Wizard separately for each size. ·        All worker nodes that are added to the cluster by using a specific worker node template define a set of worker nodes that will be deployed and managed together in Windows Azure when you start the nodes. This includes worker nodes that you add later by using the worker node template and, if you choose, worker nodes of different sizes. You cannot start, stop, or delete individual worker nodes. ·        To add Windows Azure worker nodes o   In HPC Cluster Manager: Node Management > Actions pane > Add Node à Add Node Wizard o   Select Deployment Method page - Add Azure Worker nodes o   Specify New Nodes page - select a worker node template, specify the number and size of the worker nodes ·        After you add worker nodes to the cluster, they are in the Not-Deployed state, and they have a health state of Unapproved. Before you can use the worker nodes to run jobs, you must start them and then bring them online. ·        Worker nodes are numbered consecutively in a naming series that begins with the root name AzureCN – this is non-configurable. Deploying Windows Azure Worker Nodes ·        To deploy the role instances in Windows Azure - start the worker nodes added to the HPC cluster and bring the nodes online so that they are available to run cluster jobs. This can be configured in the HPC Azure Worker Node Template – Azure Availability Policy -  to be automatic or manual. ·        The Start, Stop, and Delete actions take place on the set of worker nodes that are configured by a specific worker node template. You cannot perform one of these actions on a single worker node in a set. You also cannot perform a single action on two sets of worker nodes (specified by two different worker node templates). ·        ·          Starting a set of worker nodes deploys a set of worker role instances in Windows Azure, which can take some time to complete, depending on the number of worker nodes and the performance of Windows Azure. ·        To start worker nodes manually and bring them online o   In HPC Node Management > Navigation Pane > Nodes > List / Heat Map view - select one or more worker nodes. o   Actions pane > Start – in the Start Azure Worker Nodes dialog, select a node template. o   the state of the worker nodes changes from Not Deployed to track the provisioning progress – worker node Details Pane > Provisioning Log tab. o   If there were errors during the provisioning of one or more worker nodes, the state of those nodes is set to Unknown and the node health is set to Unapproved. To determine the reason for the failure, review the provisioning logs for the nodes. o   After a worker node starts successfully, the node state changes to Offline. To bring the nodes online, select the nodes that are in the Offline state > Bring Online. ·        Troubleshooting o   check node template. o   use telnet to test connectivity: telnet <ServiceName>.cloudapp.net 7999 o   check node status - Deployment status information appears in the service account information in the Windows Azure Portal - HPC queries this -  see  node status information for any failed nodes in HPC Node Management. ·        When role instances are deployed, file packages that were previously uploaded to the storage account using the hpcpack command are automatically installed. You can also upload file packages to storage after the worker nodes are started, and then manually install them on the worker nodes. see hpcpack (http://go.microsoft.com/fwlink/?LinkID=205514). ·        to remove a set of role instances in Windows Azure - stop the nodes by using HPC Cluster Manager (apply the Stop action). This deletes the role instances from the service and changes the state of the worker nodes in the HPC cluster to Not Deployed. ·        Each time that you start a set of worker nodes, two proxy role instances (size Small) are configured in Windows Azure to facilitate communication between HPC Cluster Manager and the worker nodes. The proxy role instances are not listed in HPC Cluster Manager after the worker nodes are added. However, the instances appear in the Windows Azure Portal. The proxy role instances incur charges in Windows Azure along with the worker node instances, and they count toward the quota of role instances in the subscription.

    Read the article

  • Heaps of Trouble?

    - by Paul White NZ
    If you’re not already a regular reader of Brad Schulz’s blog, you’re missing out on some great material.  In his latest entry, he is tasked with optimizing a query run against tables that have no indexes at all.  The problem is, predictably, that performance is not very good.  The catch is that we are not allowed to create any indexes (or even new statistics) as part of our optimization efforts. In this post, I’m going to look at the problem from a slightly different angle, and present an alternative solution to the one Brad found.  Inevitably, there’s going to be some overlap between our entries, and while you don’t necessarily need to read Brad’s post before this one, I do strongly recommend that you read it at some stage; he covers some important points that I won’t cover again here. The Example We’ll use data from the AdventureWorks database, copied to temporary unindexed tables.  A script to create these structures is shown below: CREATE TABLE #Custs ( CustomerID INTEGER NOT NULL, TerritoryID INTEGER NULL, CustomerType NCHAR(1) COLLATE SQL_Latin1_General_CP1_CI_AI NOT NULL, ); GO CREATE TABLE #Prods ( ProductMainID INTEGER NOT NULL, ProductSubID INTEGER NOT NULL, ProductSubSubID INTEGER NOT NULL, Name NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AI NOT NULL, ); GO CREATE TABLE #OrdHeader ( SalesOrderID INTEGER NOT NULL, OrderDate DATETIME NOT NULL, SalesOrderNumber NVARCHAR(25) COLLATE SQL_Latin1_General_CP1_CI_AI NOT NULL, CustomerID INTEGER NOT NULL, ); GO CREATE TABLE #OrdDetail ( SalesOrderID INTEGER NOT NULL, OrderQty SMALLINT NOT NULL, LineTotal NUMERIC(38,6) NOT NULL, ProductMainID INTEGER NOT NULL, ProductSubID INTEGER NOT NULL, ProductSubSubID INTEGER NOT NULL, ); GO INSERT #Custs ( CustomerID, TerritoryID, CustomerType ) SELECT C.CustomerID, C.TerritoryID, C.CustomerType FROM AdventureWorks.Sales.Customer C WITH (TABLOCK); GO INSERT #Prods ( ProductMainID, ProductSubID, ProductSubSubID, Name ) SELECT P.ProductID, P.ProductID, P.ProductID, P.Name FROM AdventureWorks.Production.Product P WITH (TABLOCK); GO INSERT #OrdHeader ( SalesOrderID, OrderDate, SalesOrderNumber, CustomerID ) SELECT H.SalesOrderID, H.OrderDate, H.SalesOrderNumber, H.CustomerID FROM AdventureWorks.Sales.SalesOrderHeader H WITH (TABLOCK); GO INSERT #OrdDetail ( SalesOrderID, OrderQty, LineTotal, ProductMainID, ProductSubID, ProductSubSubID ) SELECT D.SalesOrderID, D.OrderQty, D.LineTotal, D.ProductID, D.ProductID, D.ProductID FROM AdventureWorks.Sales.SalesOrderDetail D WITH (TABLOCK); The query itself is a simple join of the four tables: SELECT P.ProductMainID AS PID, P.Name, D.OrderQty, H.SalesOrderNumber, H.OrderDate, C.TerritoryID FROM #Prods P JOIN #OrdDetail D ON P.ProductMainID = D.ProductMainID AND P.ProductSubID = D.ProductSubID AND P.ProductSubSubID = D.ProductSubSubID JOIN #OrdHeader H ON D.SalesOrderID = H.SalesOrderID JOIN #Custs C ON H.CustomerID = C.CustomerID ORDER BY P.ProductMainID ASC OPTION (RECOMPILE, MAXDOP 1); Remember that these tables have no indexes at all, and only the single-column sampled statistics SQL Server automatically creates (assuming default settings).  The estimated query plan produced for the test query looks like this (click to enlarge): The Problem The problem here is one of cardinality estimation – the number of rows SQL Server expects to find at each step of the plan.  The lack of indexes and useful statistical information means that SQL Server does not have the information it needs to make a good estimate.  Every join in the plan shown above estimates that it will produce just a single row as output.  Brad covers the factors that lead to the low estimates in his post. In reality, the join between the #Prods and #OrdDetail tables will produce 121,317 rows.  It should not surprise you that this has rather dire consequences for the remainder of the query plan.  In particular, it makes a nonsense of the optimizer’s decision to use Nested Loops to join to the two remaining tables.  Instead of scanning the #OrdHeader and #Custs tables once (as it expected), it has to perform 121,317 full scans of each.  The query takes somewhere in the region of twenty minutes to run to completion on my development machine. A Solution At this point, you may be thinking the same thing I was: if we really are stuck with no indexes, the best we can do is to use hash joins everywhere. We can force the exclusive use of hash joins in several ways, the two most common being join and query hints.  A join hint means writing the query using the INNER HASH JOIN syntax; using a query hint involves adding OPTION (HASH JOIN) at the bottom of the query.  The difference is that using join hints also forces the order of the join, whereas the query hint gives the optimizer freedom to reorder the joins at its discretion. Adding the OPTION (HASH JOIN) hint results in this estimated plan: That produces the correct output in around seven seconds, which is quite an improvement!  As a purely practical matter, and given the rigid rules of the environment we find ourselves in, we might leave things there.  (We can improve the hashing solution a bit – I’ll come back to that later on). Faster Nested Loops It might surprise you to hear that we can beat the performance of the hash join solution shown above using nested loops joins exclusively, and without breaking the rules we have been set. The key to this part is to realize that a condition like (A = B) can be expressed as (A <= B) AND (A >= B).  Armed with this tremendous new insight, we can rewrite the join predicates like so: SELECT P.ProductMainID AS PID, P.Name, D.OrderQty, H.SalesOrderNumber, H.OrderDate, C.TerritoryID FROM #OrdDetail D JOIN #OrdHeader H ON D.SalesOrderID >= H.SalesOrderID AND D.SalesOrderID <= H.SalesOrderID JOIN #Custs C ON H.CustomerID >= C.CustomerID AND H.CustomerID <= C.CustomerID JOIN #Prods P ON P.ProductMainID >= D.ProductMainID AND P.ProductMainID <= D.ProductMainID AND P.ProductSubID = D.ProductSubID AND P.ProductSubSubID = D.ProductSubSubID ORDER BY D.ProductMainID OPTION (RECOMPILE, LOOP JOIN, MAXDOP 1, FORCE ORDER); I’ve also added LOOP JOIN and FORCE ORDER query hints to ensure that only nested loops joins are used, and that the tables are joined in the order they appear.  The new estimated execution plan is: This new query runs in under 2 seconds. Why Is It Faster? The main reason for the improvement is the appearance of the eager Index Spools, which are also known as index-on-the-fly spools.  If you read my Inside The Optimiser series you might be interested to know that the rule responsible is called JoinToIndexOnTheFly. An eager index spool consumes all rows from the table it sits above, and builds a index suitable for the join to seek on.  Taking the index spool above the #Custs table as an example, it reads all the CustomerID and TerritoryID values with a single scan of the table, and builds an index keyed on CustomerID.  The term ‘eager’ means that the spool consumes all of its input rows when it starts up.  The index is built in a work table in tempdb, has no associated statistics, and only exists until the query finishes executing. The result is that each unindexed table is only scanned once, and just for the columns necessary to build the temporary index.  From that point on, every execution of the inner side of the join is answered by a seek on the temporary index – not the base table. A second optimization is that the sort on ProductMainID (required by the ORDER BY clause) is performed early, on just the rows coming from the #OrdDetail table.  The optimizer has a good estimate for the number of rows it needs to sort at that stage – it is just the cardinality of the table itself.  The accuracy of the estimate there is important because it helps determine the memory grant given to the sort operation.  Nested loops join preserves the order of rows on its outer input, so sorting early is safe.  (Hash joins do not preserve order in this way, of course). The extra lazy spool on the #Prods branch is a further optimization that avoids executing the seek on the temporary index if the value being joined (the ‘outer reference’) hasn’t changed from the last row received on the outer input.  It takes advantage of the fact that rows are still sorted on ProductMainID, so if duplicates exist, they will arrive at the join operator one after the other. The optimizer is quite conservative about introducing index spools into a plan, because creating and dropping a temporary index is a relatively expensive operation.  It’s presence in a plan is often an indication that a useful index is missing. I want to stress that I rewrote the query in this way primarily as an educational exercise – I can’t imagine having to do something so horrible to a production system. Improving the Hash Join I promised I would return to the solution that uses hash joins.  You might be puzzled that SQL Server can create three new indexes (and perform all those nested loops iterations) faster than it can perform three hash joins.  The answer, again, is down to the poor information available to the optimizer.  Let’s look at the hash join plan again: Two of the hash joins have single-row estimates on their build inputs.  SQL Server fixes the amount of memory available for the hash table based on this cardinality estimate, so at run time the hash join very quickly runs out of memory. This results in the join spilling hash buckets to disk, and any rows from the probe input that hash to the spilled buckets also get written to disk.  The join process then continues, and may again run out of memory.  This is a recursive process, which may eventually result in SQL Server resorting to a bailout join algorithm, which is guaranteed to complete eventually, but may be very slow.  The data sizes in the example tables are not large enough to force a hash bailout, but it does result in multiple levels of hash recursion.  You can see this for yourself by tracing the Hash Warning event using the Profiler tool. The final sort in the plan also suffers from a similar problem: it receives very little memory and has to perform multiple sort passes, saving intermediate runs to disk (the Sort Warnings Profiler event can be used to confirm this).  Notice also that because hash joins don’t preserve sort order, the sort cannot be pushed down the plan toward the #OrdDetail table, as in the nested loops plan. Ok, so now we understand the problems, what can we do to fix it?  We can address the hash spilling by forcing a different order for the joins: SELECT P.ProductMainID AS PID, P.Name, D.OrderQty, H.SalesOrderNumber, H.OrderDate, C.TerritoryID FROM #Prods P JOIN #Custs C JOIN #OrdHeader H ON H.CustomerID = C.CustomerID JOIN #OrdDetail D ON D.SalesOrderID = H.SalesOrderID ON P.ProductMainID = D.ProductMainID AND P.ProductSubID = D.ProductSubID AND P.ProductSubSubID = D.ProductSubSubID ORDER BY D.ProductMainID OPTION (MAXDOP 1, HASH JOIN, FORCE ORDER); With this plan, each of the inputs to the hash joins has a good estimate, and no hash recursion occurs.  The final sort still suffers from the one-row estimate problem, and we get a single-pass sort warning as it writes rows to disk.  Even so, the query runs to completion in three or four seconds.  That’s around half the time of the previous hashing solution, but still not as fast as the nested loops trickery. Final Thoughts SQL Server’s optimizer makes cost-based decisions, so it is vital to provide it with accurate information.  We can’t really blame the performance problems highlighted here on anything other than the decision to use completely unindexed tables, and not to allow the creation of additional statistics. I should probably stress that the nested loops solution shown above is not one I would normally contemplate in the real world.  It’s there primarily for its educational and entertainment value.  I might perhaps use it to demonstrate to the sceptical that SQL Server itself is crying out for an index. Be sure to read Brad’s original post for more details.  My grateful thanks to him for granting permission to reuse some of his material. Paul White Email: [email protected] Twitter: @PaulWhiteNZ

    Read the article

< Previous Page | 168 169 170 171 172 173 174 175 176 177 178 179  | Next Page >