Search Results

Search found 5403 results on 217 pages for 'robert samuel white'.

Page 16/217 | < Previous Page | 12 13 14 15 16 17 18 19 20 21 22 23  | Next Page >

  • WPF4 Unleashed - how does converting child elements work?

    - by Kapol
    In chapter 2 of the book WPF4 Unleashed the author shows an example of how XAML processes type conversion. He states that <SolidColorBrush>White</SolidColorBrush> is equivalent to <SolidColorBrush Color="White"/> , because a string can be converted into a SolidColorBrush object. But how is that enough? It doesn't make sense to me. How does XAML know to which property should the value White be assigned?

    Read the article

  • Natural Search Engine Optimization - Don't "Game the System" Or You Will Get Banned!

    When focusing on natural search engine optimization, it is important that you keep the process "white hat." You see, when it comes to SEO, there are basically three schools of thought: White hat, Gray hat, and Black hat. As you can probably infer, white hat is following the rules, gray hat is a little in between, and black hat is going against parameters that Google and other major search engines have set for ethical SEO practices.

    Read the article

  • How do I prove or disprove "god" objects are wrong?

    - by honestduane
    Problem Summary: Long story short, I inherited a code base and an development team I am not allowed to replace and the use of God Objects is a big issue. Going forward, I want to have us re-factor things but I am getting push-back from the teams who want to do everything with God Objects "because its easier" and this means I would not be allowed to re-factor. I pushed back citing my years of dev experience, that I'm the new boss who was hired to know these things, etc, and so did the third party offshore companies account sales rep, and this is now at the executive level and my meeting is tomorrow and I want to go in with a lot of technical ammo to advocate best practices because I feel it will be cheaper in the long run (And I personally feel that is what the third party is worried about) for the company. My issue is from a technical level, I know its good long term but I'm having trouble with the ultra short term and 6 months term, and while its something I "know" I cant prove it with references and cited resources outside of one person (Robert C. Martin, aka Uncle Bob), as that is what I am being asked to do as I have been told having data from one person and only one person (Robert C Martin) is not good enough of an argument. Question: What are some resources I can cite directly (Title, year published, page number, quote) by well known experts in the field that explicitly say this use of "God" Objects/Classes/Systems is bad (or good, since we are looking for the most technically valid solution)? Research I have already done: I have a number of books here and I have searched their indexes for the use of the words "god object" and "god class". I found that oddly its almost never used and the copy of the GoF book I have for example, never uses it (At least according to the index in front of me) but I have found it in 2 books per the below, but I want more I can use. I checked the Wikipedia page for "God Object" and its currently a stub with little reference links so although I personally agree with that it says, It doesn't have much I can use in an environment where personal experience is not considered valid. The book cited is also considered too old to be valid by the people I am debating these technical points with as the argument they are making is that "it was once thought to be bad but nobody could prove it, and now modern software says "god" objects are good to use". I personally believe that this statement is incorrect, but I want to prove the truth, whatever it is. In Robert C Martin's "Agile Principles, Patterns, and Practices in C#" (ISBN: 0-13-185725-8, hardcover) where on page 266 it states "Everybody knows that god classes are a bad idea. We don't want to concentrate all the intelligence of a system into a single object or a single function. One of the goals of OOD is the partitioning and distribution of behavior into many classes and many function." -- And then goes on to say sometimes its better to use God Classes anyway sometimes (Citing micro-controllers as an example). In Robert C Martin's "Clean Code: A Handbook of Agile Software Craftsmanship" page 136 (And only this page) talks about the "God class" and calls it out as a prime example of a violation of the "classes should be small" rule he uses to promote the Single Responsibility Principle" starting on on page 138. The problem I have is all my references and citations come from the same person (Robert C. Martin), and am from the same single person/source. I am being told that because he is just one guy, my desire to not use "God Classes" is invalid and not accepted as a standard best practice in the software industry. Is this true? Am I doing things wrong from a technical perspective by trying to keep to the teaching of Uncle Bob? God Objects and Object Oriented Programming and Design: The more I think of this the more I think this is more something you learn when you study OOP and its never explicitly called out; Its implicit to good design is my thinking (Feel free to correct me, please, as I want to learn), The problem is I "know" this, but but not everybody does, so in this case its not considered a valid argument because I am effectively calling it out as universal truth when in fact most people are statistically ignorant of it since statistically most people are not programmers. Conclusion: I am at a loss on what to search for to get the best additional results to cite, since they are making a technical claim and I want to know the truth and be able to prove it with citations like a real engineer/scientist, even if I am biased against god objects due to my personal experience with code that used them. Any assistance or citations would be deeply appreciated.

    Read the article

  • Why is 1px sometimes 2px when specified in Android XML?

    - by Daniel Lew
    I've got a desire for a one-pixel divider line, just for looks. I thought I could accomplish this using a View of height 1px, with a defined background. However, I'm getting some very odd behavior on different devices - sometimes the 1px ends up as 2px. Take this sample layout for example: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="@android:color/white" android:layout_marginBottom="4dp" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="@android:color/white" android:layout_marginBottom="4dp" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="@android:color/white" android:layout_marginBottom="4dp" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="@android:color/white" android:layout_marginBottom="4dp" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="@android:color/white" android:layout_marginBottom="4dp" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="@android:color/white" android:layout_marginBottom="4dp" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:background="@android:color/white" android:layout_marginBottom="4dp" /> </LinearLayout> When run on my G1, this comes out fine. But on the Nexus One, it alternates between 1px lines and 2px lines. Does anyone know where this is going awry? Why does Android sometimes make 1px into 2px?

    Read the article

  • multi_index composite_key replace with iterator

    - by Rohit
    Is there anyway to loop through an index in a boost::multi_index and perform a replace? #include <iostream> #include <string> #include <boost/multi_index_container.hpp> #include <boost/multi_index/composite_key.hpp> #include <boost/multi_index/member.hpp> #include <boost/multi_index/ordered_index.hpp> using namespace boost::multi_index; using namespace std; struct name_record { public: name_record(string given_name_,string family_name_,string other_name_) { given_name=given_name_; family_name=family_name_; other_name=other_name_; } string given_name; string family_name; string other_name; string get_name() const { return given_name + " " + family_name + " " + other_name; } void setnew(string chg) { given_name = given_name + chg; family_name = family_name + chg; } }; struct NameIndex{}; typedef multi_index_container< name_record, indexed_by< ordered_non_unique< tag<NameIndex>, composite_key < name_record, BOOST_MULTI_INDEX_MEMBER(name_record,string, name_record::given_name), BOOST_MULTI_INDEX_MEMBER(name_record,string, name_record::family_name) > > > > name_record_set; typedef boost::multi_index::index<name_record_set,NameIndex>::type::iterator IteratorType; typedef boost::multi_index::index<name_record_set,NameIndex>::type NameIndexType; void printContainer(name_record_set & ns) { cout << endl << "PrintContainer" << endl << "-------------" << endl; IteratorType it1 = ns.begin(); IteratorType it2 = ns.end (); while (it1 != it2) { cout<<it1->get_name()<<endl; it1++; } cout << "--------------" << endl << endl; } void modifyContainer(name_record_set & ns) { cout << endl << "ModifyContainer" << endl << "-------------" << endl; IteratorType it3; IteratorType it4; NameIndexType & idx1 = ns.get<NameIndex>(); IteratorType it1 = idx1.begin(); IteratorType it2 = idx1.end(); while (it1 != it2) { cout<<it1->get_name()<<endl; name_record nr = *it1; nr.setnew("_CHG"); bool res = idx1.replace(it1,nr); cout << "result is: " << res << endl; it1++; } cout << "--------------" << endl << endl; } int main() { name_record_set ns; ns.insert( name_record("Joe","Smith","ENTRY1") ); ns.insert( name_record("Robert","Brown","ENTRY2") ); ns.insert( name_record("Robert","Nightingale","ENTRY3") ); ns.insert( name_record("Marc","Tuxedo","ENTRY4") ); printContainer (ns); modifyContainer (ns); printContainer (ns); return 0; } PrintContainer ------------- Joe Smith ENTRY1 Marc Tuxedo ENTRY4 Robert Brown ENTRY2 Robert Nightingale ENTRY3 -------------- ModifyContainer ------------- Joe Smith ENTRY1 result is: 1 Marc Tuxedo ENTRY4 result is: 1 Robert Brown ENTRY2 result is: 1 -------------- PrintContainer ------------- Joe_CHG Smith_CHG ENTRY1 Marc_CHG Tuxedo_CHG ENTRY4 Robert Nightingale ENTRY3 Robert_CHG Brown_CHG ENTRY2 --------------

    Read the article

  • Troubleshooting Your Network with Oracle Linux

    - by rickramsey
    Are you afraid of network problems? I was. Whenever somebody said "it's probably the network," I went to lunch. And hoped that it was fixed by the time I got back. Turns out it wasn't that hard to do a little basic troubleshooting Tech Article: Troubleshooting Your Network with Oracle Linux by Robert Chase You're no doubt already familiar with ping. Even I knew how to use ping. Turns out there's another command that can show you not just whether a system can respond over the network, but the path the packets to that system take. Our blogging platform won't allow me to write the name down, but I can tell you that if you replace the x in this word with an e, you'll have the right command: tracxroute Once you get used to those, you can venture into the realms of mtr, nmap, and netcap. Robert Chase explains how each one can help you troubleshoot the network, and provides examples for how to use them. Robert is not only a solid writer, he is also a brilliant motorcyclist and rides an MV Augusta F4 750. About the Photograph Photo of flowers in San Simeon, California, taken by Rick Ramsey on a ride home from the Sun Reunion in May 2014. - Rick Follow me on: Personal Blog | Personal Twitter   Follow OTN Garage on: Web | Facebook | Twitter | YouTube

    Read the article

  • Shortest Path algorithm of a different kind

    - by Ram Bhat
    Hey guys, Lets say you have a grid like this (made randomly) Now lets say you have a car starting randomly from one of the while boxes, what would be the shortest path to go through each one of the white boxes? you can visit each white box as many times as you want and cant Jump over the black boxes. The black boxes are like walls. In simple words you can move from white box to white box only.. You can move in any direction, even diagonally.

    Read the article

  • Ajax Tabs implementation problem .

    - by SmartDev
    Hi , I have Implement ajax tabs and i have four tabs in it . In the four tabs i have four grid views with paging and sorting .The tabs are looking good i can see the grid ,but the problem is my first tab sorting works fine, where if i click on any other tab and click on the grid it goes to my first tab again . One more thing i want to change the background color of each tab. Can anyone help please here is my source code: <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> <asp:ScriptManager ID="ScMMyTabs" runat="server"> </asp:ScriptManager> <cc1:TabContainer ID="TCMytabs" ActiveTabIndex="0" runat="server"> <cc1:TabPanel ID="TpMyreq" runat="server" CssClass="TabBackground" HeaderText="My request"> <ContentTemplate> <table> <tr> <td> <asp:Button ID="btnexportMyRequestCsu" runat="server" Text="Export To Excel" CssClass="LabelDisplay" OnClick="btnexportMyRequestCsu_Click" /> </td> </tr> <tr> <td> <asp:GridView ID="GdvMyrequest" runat="server" CssClass="Mytabs" BackColor="White" BorderColor="White" BorderStyle="Ridge" BorderWidth="2px" CellPadding="3" CellSpacing="1" GridLines="None" OnPageIndexChanging="GdvMyrequest_PageIndexChanging" OnSorting="GdvMyrequest_Sorting" EmptyDataText="No request found for this user"> <RowStyle BackColor="#DEDFDE" ForeColor="Black" /> <FooterStyle BackColor="#C6C3C6" ForeColor="Black" /> <PagerStyle BackColor="Control" ForeColor="Gray" HorizontalAlign="Left" /> <SelectedRowStyle BackColor="#9471DE" Font-Bold="True" ForeColor="White" /> <HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#E7E7FF" /> <PagerSettings Position="TopAndBottom" /> <Columns> <asp:TemplateField> <HeaderTemplate> Row No </HeaderTemplate> <ItemTemplate> <%# Container.DataItemIndex + 1 %> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> </td> </tr> <tr> <td> <asp:Label ID="lblmessmyrequestAhk" runat="server" CssClass="labelmess"></asp:Label> </td> </tr> </table> </ContentTemplate> </cc1:TabPanel> <cc1:TabPanel ID="TpMyPaymentCc" runat="server" HeaderText="Payments Credit Card" > <ContentTemplate> <table> <tr> <td> <asp:GridView ID="GdvmypaymentsCc" runat="server" CssClass="Mytabs" BackColor="White" BorderColor="White" BorderStyle="Ridge" BorderWidth="2px" CellPadding="3" CellSpacing="1" GridLines="None" OnPageIndexChanging="GdvmypaymentsCc_PageIndexChanging" OnSorting="GdvmypaymentsCc_Sorting" EmptyDataText="No Data"> <RowStyle BackColor="#DEDFDE" ForeColor="Black" /> <FooterStyle BackColor="#C6C3C6" ForeColor="Black" /> <PagerStyle BackColor="Control" ForeColor="Gray" HorizontalAlign="Left" /> <SelectedRowStyle BackColor="#9471DE" Font-Bold="True" ForeColor="White" /> <HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#E7E7FF" /> <PagerSettings Position="TopAndBottom" /> </asp:GridView> </td> </tr> <tr> <td> <asp:Label ID="lblmessmypaymentsCsu" runat="server" CssClass="labelmess"></asp:Label> </td> </tr> </table> </ContentTemplate> </cc1:TabPanel> <cc1:TabPanel ID="TpMyPaymentsCk" runat="server" HeaderText="Payments Check" > <ContentTemplate> <asp:GridView ID="GdvmypaymentsCk" runat="server" CssClass="Mytabs" BackColor="White" BorderColor="White" BorderStyle="Ridge" BorderWidth="2px" CellPadding="3" CellSpacing="1" GridLines="None" OnPageIndexChanging="GdvmypaymentsCk_PageIndexChanging" OnSorting="GdvmypaymentsCk_Sorting" EmptyDataText="No Data"> <RowStyle BackColor="#DEDFDE" ForeColor="Black" /> <FooterStyle BackColor="#C6C3C6" ForeColor="Black" /> <PagerStyle BackColor="Control" ForeColor="Gray" HorizontalAlign="Left" /> <SelectedRowStyle BackColor="#9471DE" Font-Bold="True" ForeColor="White" /> <HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#E7E7FF" /> <PagerSettings Position="TopAndBottom" /> </asp:GridView> </ContentTemplate> </cc1:TabPanel> <cc1:TabPanel ID="TpMyCalls" runat="server" HeaderText="Calls" > <ContentTemplate> <table> <tr> <td> <asp:GridView ID="GdvSelectcallsP" runat="server" CssClass="Mytabs" BackColor="White" BorderColor="White" BorderStyle="Ridge" BorderWidth="2px" CellPadding="3" CellSpacing="1" GridLines="None" OnPageIndexChanging="GdvSelectcallsP_PageIndexChanging" OnRowDataBound="GdvSelectcallsP_RowDataBound" OnSorting="GdvSelectcallsP_Sorting" > <RowStyle BackColor="#DEDFDE" ForeColor="Black" /> <FooterStyle BackColor="#C6C3C6" ForeColor="Black" /> <PagerStyle BackColor="#C6C3C6" ForeColor="Black" HorizontalAlign="Right" /> <SelectedRowStyle BackColor="#9471DE" Font-Bold="True" ForeColor="White" /> <HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#E7E7FF" /> <Columns> <asp:TemplateField> <HeaderTemplate> Row No </HeaderTemplate> <ItemTemplate> <%# Container.DataItemIndex + 1 %> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> </td> </tr> <tr> <td> <asp:Label ID="lblmessselectcallsAhkP" runat="server" CssClass="labelmess"></asp:Label> </td> </tr> </table> </ContentTemplate> </cc1:TabPanel> </cc1:TabContainer> </asp:Content>

    Read the article

  • Installing Recaptcha in Joomla 1.5 user registration

    - by Samuel
    I am trying to install ReCaptcha into the user registration of Joomla 1.5. This may just be an issue with Joomla but when i hit register nothing happens. I think it's doing some JavaScript form validation but there is nothing telling the user what went wrong. if, God forbid, they do fill out the form correctly Joomla will redirect the user to the homepage and give no notice of success. Is this a Joomla issue or is there something wrong with my install? Does anyone know of a plug-in or module for Joomla that would make this easier? Thanks in advance, Samuel UPDATE: Joomla does a lot of "stuff"/"something" to the $_POST and $_GET variables which was causing the reCaptcha to not function. This was for work which is past so I am not spending anymore time on it. Shameless Plug: use wordpress instead. this can be closed as I don't have time to verify which answer works

    Read the article

  • Am i passing values or adresses? [Java]

    - by Samuel
    Hello World, I am new to java and i was asking myself, if i have a class 'Example' and somewhere i make a: Example example1 = new Example(); and i add some stuff to it, lets say example1.setExampleBoolean(false); and now i make: Example example2 = example1; example2.setExampleBoolean(true); Did i say with Example example2 = example1 let example2 point to the same adress as example1? Because than i would have altered example1. In other words would, using something like: Boolean exampleBoolean = example1.getExampleBoolean(); exampleBoolean be true of false? Might be a stupid questions but for me it would change the way i'd handle problems in my programs :) Thanks in advance -Samuel

    Read the article

  • Date object to Calendar [Java]

    - by Samuel
    Hello World, I have a class Movie in it i have a start Date, a duration and a stop Date. Start and stop Date are Date Objects (private Date startDate ...) (It's an assignment so i cant change that) now i want to automatically calculate the stopDate by adding the duration (in min) to the startDate. By my knowledge working with the time manipulating functions of Date is deprecated hence bad practice but on the other side i see no way to convert the Date object to a calendar object in order to manipulate the time and reconvert it to a Date object. Is there a way? And if there is what would be best practice Thanks in advance Samuel

    Read the article

  • Use method not defined in Interface [Java]

    - by Samuel
    Hello World, I have an assignment and i got a library including an interface class. [InfoItem] I implement this class [Item]. Now i am required to write a method watchProgram(InfoItem item) [other class, importing InfoItem], which (as shown) requires an InfoItem. The passed parameter item has a variable 'Recorded' [boolean] which i want to edit using a method changeRecorded() that i defined in the implementation of InfoItem. I cannot edit the interface and i get an error message that the method is not found [cannot find symbol].. Any hints, suggestions, solutions? Thanks!! -Samuel-

    Read the article

  • Sort ArrayList of custom Objects by property

    - by Samuel
    Hello World!! :D I had a question which is pretty easy if you know the answer I guess. I read about sorting ArrayLists using a Comparator but somehow in all of the examples people used compareTo which according to some research is a method working on Strings... I wanted to sort an ArrayList of custom objects by one of their properties: a Date object (getStartDay()). Normally I compare them by item1.getStartDate().before(item2.getStartDate()) so I was wondering whether I could write something like: public class customComparator { public boolean compare(Object object1, Object object2) { return object1.getStartDate().before(object2.getStartDate()); } } public class randomName { ... Collections.sort(Database.arrayList, new customComparator); ... } I just started with Java so please forgive my ignorance :) Thanks in advance!! -Samuel

    Read the article

  • Address calling class [Java]

    - by Samuel
    Hello! [I am rather new to Java and Object Oriented programming] I have an abstract class Moveable with the method abstract void move() which is extended by the class Bullet and the abstract class Character, and Character is extended by the class Survivor and the class Zombie. In Survivor and Bullet the move() method doesnt require any parameters while in the class Zombie the move() method depends on the actual position of the survivor. The survivor and multiple zombies are created in the class Gui. I wanted to access the survivor in Zombie - what's the best way of doing this? In Gui i wrote a method getSurvivor() but i don't see how to access this method in Zombie? I am aware that as a workaround i could just pass a [Survivor survivor] as parameter in move() and ignore it in Bullet and Survivor, but that feels so ... bad practice. Thank you for your time! Samuel [I am not sure what tags to set here, please correct me if i'm wrong]

    Read the article

  • Mix RGB colors (L*a*b*)

    - by Samuel
    Hello! Basically I want two mix two colours color1 and color2. Since simple calculation's bring up stuff like blue+yellow = grey ((color1.r + color2.r)/2 etc) i did some research and found that apparently mixing colors in order for the mixed color to look like we expect it too (e.g. blue+yellow = green) isn't that straight forward. What another stackoverflow post taught me was that in order two achieve the mixture correctly i'd have to use the L*a*b* space / CIELAB and linked to the wikipedia page about this topic. I found it informative but i couldn't really understand how to convert RGB to (sRGB and than to) L*a*b* - how to mix the obtained colors and how to convert back I hope somebody here can help me Thanks, Samuel

    Read the article

  • Chaotic behavior of a dead pixel on my iMac 24"

    - by Vincent Robert
    Since I bought my iMac last year, I have a white pixel on the left of my screen. I'm ok with that, one pixel is not much and I know about dead pixels policies. My problem is about understanding this "dead" pixel. But this pixel has a strange behavior. At first, it seems to be always white, but it is actually working ok under certain conditions: the mouse pointer a contextual menu Dock icons a QuickLooks video played in fullscreen other spaces than "1" The "QuickLooks fullscreen video" and "other spaces" are the one that disturb me the most. In these modes, my pixel is working fine, so it must be a software problem since my pixel is working correctly in those modes. Any ideas?

    Read the article

  • Cardinality Estimation Bug with Lookups in SQL Server 2008 onward

    - by Paul White
    Cost-based optimization stands or falls on the quality of cardinality estimates (expected row counts).  If the optimizer has incorrect information to start with, it is quite unlikely to produce good quality execution plans except by chance.  There are many ways we can provide good starting information to the optimizer, and even more ways for cardinality estimation to go wrong.  Good database people know this, and work hard to write optimizer-friendly queries with a schema and metadata (e.g. statistics) that reduce the chances of poor cardinality estimation producing a sub-optimal plan.  Today, I am going to look at a case where poor cardinality estimation is Microsoft’s fault, and not yours. SQL Server 2005 SELECT th.ProductID, th.TransactionID, th.TransactionDate FROM Production.TransactionHistory AS th WHERE th.ProductID = 1 AND th.TransactionDate BETWEEN '20030901' AND '20031231'; The query plan on SQL Server 2005 is as follows (if you are using a more recent version of AdventureWorks, you will need to change the year on the date range from 2003 to 2007): There is an Index Seek on ProductID = 1, followed by a Key Lookup to find the Transaction Date for each row, and finally a Filter to restrict the results to only those rows where Transaction Date falls in the range specified.  The cardinality estimate of 45 rows at the Index Seek is exactly correct.  The table is not very large, there are up-to-date statistics associated with the index, so this is as expected. The estimate for the Key Lookup is also exactly right.  Each lookup into the Clustered Index to find the Transaction Date is guaranteed to return exactly one row.  The plan shows that the Key Lookup is expected to be executed 45 times.  The estimate for the Inner Join output is also correct – 45 rows from the seek joining to one row each time, gives 45 rows as output. The Filter estimate is also very good: the optimizer estimates 16.9951 rows will match the specified range of transaction dates.  Eleven rows are produced by this query, but that small difference is quite normal and certainly nothing to worry about here.  All good so far. SQL Server 2008 onward The same query executed against an identical copy of AdventureWorks on SQL Server 2008 produces a different execution plan: The optimizer has pushed the Filter conditions seen in the 2005 plan down to the Key Lookup.  This is a good optimization – it makes sense to filter rows out as early as possible.  Unfortunately, it has made a bit of a mess of the cardinality estimates. The post-Filter estimate of 16.9951 rows seen in the 2005 plan has moved with the predicate on Transaction Date.  Instead of estimating one row, the plan now suggests that 16.9951 rows will be produced by each clustered index lookup – clearly not right!  This misinformation also confuses SQL Sentry Plan Explorer: Plan Explorer shows 765 rows expected from the Key Lookup (it multiplies a rounded estimate of 17 rows by 45 expected executions to give 765 rows total). Workarounds One workaround is to provide a covering non-clustered index (avoiding the lookup avoids the problem of course): CREATE INDEX nc1 ON Production.TransactionHistory (ProductID) INCLUDE (TransactionDate); With the Transaction Date filter applied as a residual predicate in the same operator as the seek, the estimate is again as expected: We could also force the use of the ultimate covering index (the clustered one): SELECT th.ProductID, th.TransactionID, th.TransactionDate FROM Production.TransactionHistory AS th WITH (INDEX(1)) WHERE th.ProductID = 1 AND th.TransactionDate BETWEEN '20030901' AND '20031231'; Summary Providing a covering non-clustered index for all possible queries is not always practical, and scanning the clustered index will rarely be optimal.  Nevertheless, these are the best workarounds we have today. In the meantime, watch out for poor cardinality estimates when a predicate is applied as part of a lookup. The worst thing is that the estimate after the lookup join in the 2008+ plans is wrong.  It’s not hopelessly wrong in this particular case (45 versus 16.9951 is not the end of the world) but it easily can be much worse, and there’s not much you can do about it.  Any decisions made by the optimizer after such a lookup could be based on very wrong information – which can only be bad news. If you think this situation should be improved, please vote for this Connect item. © 2012 Paul White – All Rights Reserved twitter: @SQL_Kiwi email: [email protected]

    Read the article

  • Deleting xml file using radio value

    - by ???? ???
    i using php to delete file, but i got table loop like this: <table border="0" width="100%" cellpadding="0" cellspacing="0" id="product-table"> <tr class="bg_tableheader"> <th class="table-header-check"><a id="toggle-all" ></a> </th> <th class="table-header-check"><a href="#"><font color="white">Username</font></a> </th> <th class="table-header-check"><a href="#"><font color="white">First Name</font></a></th> <th class="table-header-check"><a href="#"><font color="white">Last Name</font></a></th> <th class="table-header-check"><a href="#"><font color="white">Email</font></a></th> <th class="table-header-check"><a href="#"><font color="white">Group</font></a></th> <th class="table-header-check"><a href="#"><font color="white">Birthday</font></a></th> <th class="table-header-check"><a href="#"><font color="white">Gender</font></a></th> <th class="table-header-check"><a href="#"><font color="white">Age</font></a></th> <th class="table-header-check"><a href="#"><font color="white">Country</font></a></th> </tr> <?php $files = glob('users/*.xml'); foreach($files as $file){ $xml = new SimpleXMLElement($file, 0, true); echo ' <tr> <td></td> <form action="" method="post"> <td class="alternate-row1"><input type="radio" name="file_name" value="'. basename($file, '.xml') .'" />'. basename($file, '.xml') .'</td> <td>'. $xml->name .'&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</td> <td class="alternate-row1">'. $xml->lastname .'</td> <td>'. $xml->email .'</td> <td class="alternate-row1">'. $xml->level .'</td> <td>'. $xml->birthday .'</td> <td class="alternate-row1">'. $xml->gender .'</td> <td>'. $xml->age .'</td> <td class="alternate-row1">'. $xml->country .'</td> </tr>'; } ?> </table> </div> <?php if(isset($_POST['file_name'])){ unlink('users/'.$_POST['file_name']); } ?> <input type="submit" value="Delete" /> </form> so as you can see i got radio value set has basename (xml file name) but from some reason it not working, any idea why is that? Thanks in advance.

    Read the article

  • Fun with Aggregates

    - by Paul White
    There are interesting things to be learned from even the simplest queries.  For example, imagine you are given the task of writing a query to list AdventureWorks product names where the product has at least one entry in the transaction history table, but fewer than ten. One possible query to meet that specification is: SELECT p.Name FROM Production.Product AS p JOIN Production.TransactionHistory AS th ON p.ProductID = th.ProductID GROUP BY p.ProductID, p.Name HAVING COUNT_BIG(*) < 10; That query correctly returns 23 rows (execution plan and data sample shown below): The execution plan looks a bit different from the written form of the query: the base tables are accessed in reverse order, and the aggregation is performed before the join.  The general idea is to read all rows from the history table, compute the count of rows grouped by ProductID, merge join the results to the Product table on ProductID, and finally filter to only return rows where the count is less than ten. This ‘fully-optimized’ plan has an estimated cost of around 0.33 units.  The reason for the quote marks there is that this plan is not quite as optimal as it could be – surely it would make sense to push the Filter down past the join too?  To answer that, let’s look at some other ways to formulate this query.  This being SQL, there are any number of ways to write logically-equivalent query specifications, so we’ll just look at a couple of interesting ones.  The first query is an attempt to reverse-engineer T-SQL from the optimized query plan shown above.  It joins the result of pre-aggregating the history table to the Product table before filtering: SELECT p.Name FROM ( SELECT th.ProductID, cnt = COUNT_BIG(*) FROM Production.TransactionHistory AS th GROUP BY th.ProductID ) AS q1 JOIN Production.Product AS p ON p.ProductID = q1.ProductID WHERE q1.cnt < 10; Perhaps a little surprisingly, we get a slightly different execution plan: The results are the same (23 rows) but this time the Filter is pushed below the join!  The optimizer chooses nested loops for the join, because the cardinality estimate for rows passing the Filter is a bit low (estimate 1 versus 23 actual), though you can force a merge join with a hint and the Filter still appears below the join.  In yet another variation, the < 10 predicate can be ‘manually pushed’ by specifying it in a HAVING clause in the “q1” sub-query instead of in the WHERE clause as written above. The reason this predicate can be pushed past the join in this query form, but not in the original formulation is simply an optimizer limitation – it does make efforts (primarily during the simplification phase) to encourage logically-equivalent query specifications to produce the same execution plan, but the implementation is not completely comprehensive. Moving on to a second example, the following query specification results from phrasing the requirement as “list the products where there exists fewer than ten correlated rows in the history table”: SELECT p.Name FROM Production.Product AS p WHERE EXISTS ( SELECT * FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID HAVING COUNT_BIG(*) < 10 ); Unfortunately, this query produces an incorrect result (86 rows): The problem is that it lists products with no history rows, though the reasons are interesting.  The COUNT_BIG(*) in the EXISTS clause is a scalar aggregate (meaning there is no GROUP BY clause) and scalar aggregates always produce a value, even when the input is an empty set.  In the case of the COUNT aggregate, the result of aggregating the empty set is zero (the other standard aggregates produce a NULL).  To make the point really clear, let’s look at product 709, which happens to be one for which no history rows exist: -- Scalar aggregate SELECT COUNT_BIG(*) FROM Production.TransactionHistory AS th WHERE th.ProductID = 709;   -- Vector aggregate SELECT COUNT_BIG(*) FROM Production.TransactionHistory AS th WHERE th.ProductID = 709 GROUP BY th.ProductID; The estimated execution plans for these two statements are almost identical: You might expect the Stream Aggregate to have a Group By for the second statement, but this is not the case.  The query includes an equality comparison to a constant value (709), so all qualified rows are guaranteed to have the same value for ProductID and the Group By is optimized away. In fact there are some minor differences between the two plans (the first is auto-parameterized and qualifies for trivial plan, whereas the second is not auto-parameterized and requires cost-based optimization), but there is nothing to indicate that one is a scalar aggregate and the other is a vector aggregate.  This is something I would like to see exposed in show plan so I suggested it on Connect.  Anyway, the results of running the two queries show the difference at runtime: The scalar aggregate (no GROUP BY) returns a result of zero, whereas the vector aggregate (with a GROUP BY clause) returns nothing at all.  Returning to our EXISTS query, we could ‘fix’ it by changing the HAVING clause to reject rows where the scalar aggregate returns zero: SELECT p.Name FROM Production.Product AS p WHERE EXISTS ( SELECT * FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID HAVING COUNT_BIG(*) BETWEEN 1 AND 9 ); The query now returns the correct 23 rows: Unfortunately, the execution plan is less efficient now – it has an estimated cost of 0.78 compared to 0.33 for the earlier plans.  Let’s try adding a redundant GROUP BY instead of changing the HAVING clause: SELECT p.Name FROM Production.Product AS p WHERE EXISTS ( SELECT * FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID GROUP BY th.ProductID HAVING COUNT_BIG(*) < 10 ); Not only do we now get correct results (23 rows), this is the execution plan: I like to compare that plan to quantum physics: if you don’t find it shocking, you haven’t understood it properly :)  The simple addition of a redundant GROUP BY has resulted in the EXISTS form of the query being transformed into exactly the same optimal plan we found earlier.  What’s more, in SQL Server 2008 and later, we can replace the odd-looking GROUP BY with an explicit GROUP BY on the empty set: SELECT p.Name FROM Production.Product AS p WHERE EXISTS ( SELECT * FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID GROUP BY () HAVING COUNT_BIG(*) < 10 ); I offer that as an alternative because some people find it more intuitive (and it perhaps has more geek value too).  Whichever way you prefer, it’s rather satisfying to note that the result of the sub-query does not exist for a particular correlated value where a vector aggregate is used (the scalar COUNT aggregate always returns a value, even if zero, so it always ‘EXISTS’ regardless which ProductID is logically being evaluated). The following query forms also produce the optimal plan and correct results, so long as a vector aggregate is used (you can probably find more equivalent query forms): WHERE Clause SELECT p.Name FROM Production.Product AS p WHERE ( SELECT COUNT_BIG(*) FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID GROUP BY () ) < 10; APPLY SELECT p.Name FROM Production.Product AS p CROSS APPLY ( SELECT NULL FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID GROUP BY () HAVING COUNT_BIG(*) < 10 ) AS ca (dummy); FROM Clause SELECT q1.Name FROM ( SELECT p.Name, cnt = ( SELECT COUNT_BIG(*) FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID GROUP BY () ) FROM Production.Product AS p ) AS q1 WHERE q1.cnt < 10; This last example uses SUM(1) instead of COUNT and does not require a vector aggregate…you should be able to work out why :) SELECT q.Name FROM ( SELECT p.Name, cnt = ( SELECT SUM(1) FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID ) FROM Production.Product AS p ) AS q WHERE q.cnt < 10; The semantics of SQL aggregates are rather odd in places.  It definitely pays to get to know the rules, and to be careful to check whether your queries are using scalar or vector aggregates.  As we have seen, query plans do not show in which ‘mode’ an aggregate is running and getting it wrong can cause poor performance, wrong results, or both. © 2012 Paul White Twitter: @SQL_Kiwi email: [email protected]

    Read the article

  • I see no LOBs!

    - by Paul White
    Is it possible to see LOB (large object) logical reads from STATISTICS IO output on a table with no LOB columns? I was asked this question today by someone who had spent a good fraction of their afternoon trying to work out why this was occurring – even going so far as to re-run DBCC CHECKDB to see if any corruption had taken place.  The table in question wasn’t particularly pretty – it had grown somewhat organically over time, with new columns being added every so often as the need arose.  Nevertheless, it remained a simple structure with no LOB columns – no TEXT or IMAGE, no XML, no MAX types – nothing aside from ordinary INT, MONEY, VARCHAR, and DATETIME types.  To add to the air of mystery, not every query that ran against the table would report LOB logical reads – just sometimes – but when it did, the query often took much longer to execute. Ok, enough of the pre-amble.  I can’t reproduce the exact structure here, but the following script creates a table that will serve to demonstrate the effect: IF OBJECT_ID(N'dbo.Test', N'U') IS NOT NULL DROP TABLE dbo.Test GO CREATE TABLE dbo.Test ( row_id NUMERIC IDENTITY NOT NULL,   col01 NVARCHAR(450) NOT NULL, col02 NVARCHAR(450) NOT NULL, col03 NVARCHAR(450) NOT NULL, col04 NVARCHAR(450) NOT NULL, col05 NVARCHAR(450) NOT NULL, col06 NVARCHAR(450) NOT NULL, col07 NVARCHAR(450) NOT NULL, col08 NVARCHAR(450) NOT NULL, col09 NVARCHAR(450) NOT NULL, col10 NVARCHAR(450) NOT NULL, CONSTRAINT [PK dbo.Test row_id] PRIMARY KEY CLUSTERED (row_id) ) ; The next script loads the ten variable-length character columns with one-character strings in the first row, two-character strings in the second row, and so on down to the 450th row: WITH Numbers AS ( -- Generates numbers 1 - 450 inclusive SELECT TOP (450) n = ROW_NUMBER() OVER (ORDER BY (SELECT 0)) FROM master.sys.columns C1, master.sys.columns C2, master.sys.columns C3 ORDER BY n ASC ) INSERT dbo.Test WITH (TABLOCKX) SELECT REPLICATE(N'A', N.n), REPLICATE(N'B', N.n), REPLICATE(N'C', N.n), REPLICATE(N'D', N.n), REPLICATE(N'E', N.n), REPLICATE(N'F', N.n), REPLICATE(N'G', N.n), REPLICATE(N'H', N.n), REPLICATE(N'I', N.n), REPLICATE(N'J', N.n) FROM Numbers AS N ORDER BY N.n ASC ; Once those two scripts have run, the table contains 450 rows and 10 columns of data like this: Most of the time, when we query data from this table, we don’t see any LOB logical reads, for example: -- Find the maximum length of the data in -- column 5 for a range of rows SELECT result = MAX(DATALENGTH(T.col05)) FROM dbo.Test AS T WHERE row_id BETWEEN 50 AND 100 ; But with a different query… -- Read all the data in column 1 SELECT result = MAX(DATALENGTH(T.col01)) FROM dbo.Test AS T ; …suddenly we have 49 LOB logical reads, as well as the ‘normal’ logical reads we would expect. The Explanation If we had tried to create this table in SQL Server 2000, we would have received a warning message to say that future INSERT or UPDATE operations on the table might fail if the resulting row exceeded the in-row storage limit of 8060 bytes.  If we needed to store more data than would fit in an 8060 byte row (including internal overhead) we had to use a LOB column – TEXT, NTEXT, or IMAGE.  These special data types store the large data values in a separate structure, with just a small pointer left in the original row. Row Overflow SQL Server 2005 introduced a feature called row overflow, which allows one or more variable-length columns in a row to move to off-row storage if the data in a particular row would otherwise exceed 8060 bytes.  You no longer receive a warning when creating (or altering) a table that might need more than 8060 bytes of in-row storage; if SQL Server finds that it can no longer fit a variable-length column in a particular row, it will silently move one or more of these columns off the row into a separate allocation unit. Only variable-length columns can be moved in this way (for example the (N)VARCHAR, VARBINARY, and SQL_VARIANT types).  Fixed-length columns (like INTEGER and DATETIME for example) never move into ‘row overflow’ storage.  The decision to move a column off-row is done on a row-by-row basis – so data in a particular column might be stored in-row for some table records, and off-row for others. In general, if SQL Server finds that it needs to move a column into row-overflow storage, it moves the largest variable-length column record for that row.  Note that in the case of an UPDATE statement that results in the 8060 byte limit being exceeded, it might not be the column that grew that is moved! Sneaky LOBs Anyway, that’s all very interesting but I don’t want to get too carried away with the intricacies of row-overflow storage internals.  The point is that it is now possible to define a table with non-LOB columns that will silently exceed the old row-size limit and result in ordinary variable-length columns being moved to off-row storage.  Adding new columns to a table, expanding an existing column definition, or simply storing more data in a column than you used to – all these things can result in one or more variable-length columns being moved off the row. Note that row-overflow storage is logically quite different from old-style LOB and new-style MAX data type storage – individual variable-length columns are still limited to 8000 bytes each – you can just have more of them now.  Having said that, the physical mechanisms involved are very similar to full LOB storage – a column moved to row-overflow leaves a 24-byte pointer record in the row, and the ‘separate storage’ I have been talking about is structured very similarly to both old-style LOBs and new-style MAX types.  The disadvantages are also the same: when SQL Server needs a row-overflow column value it needs to follow the in-row pointer a navigate another chain of pages, just like retrieving a traditional LOB. And Finally… In the example script presented above, the rows with row_id values from 402 to 450 inclusive all exceed the total in-row storage limit of 8060 bytes.  A SELECT that references a column in one of those rows that has moved to off-row storage will incur one or more lob logical reads as the storage engine locates the data.  The results on your system might vary slightly depending on your settings, of course; but in my tests only column 1 in rows 402-450 moved off-row.  You might like to play around with the script – updating columns, changing data type lengths, and so on – to see the effect on lob logical reads and which columns get moved when.  You might even see row-overflow columns moving back in-row if they are updated to be smaller (hint: reduce the size of a column entry by at least 1000 bytes if you hope to see this). Be aware that SQL Server will not warn you when it moves ‘ordinary’ variable-length columns into overflow storage, and it can have dramatic effects on performance.  It makes more sense than ever to choose column data types sensibly.  If you make every column a VARCHAR(8000) or NVARCHAR(4000), and someone stores data that results in a row needing more than 8060 bytes, SQL Server might turn some of your column data into pseudo-LOBs – all without saying a word. Finally, some people make a distinction between ordinary LOBs (those that can hold up to 2GB of data) and the LOB-like structures created by row-overflow (where columns are still limited to 8000 bytes) by referring to row-overflow LOBs as SLOBs.  I find that quite appealing, but the ‘S’ stands for ‘small’, which makes expanding the whole acronym a little daft-sounding…small large objects anyone? © Paul White 2011 email: [email protected] twitter: @SQL_Kiwi

    Read the article

  • When is a Seek not a Seek?

    - by Paul White
    The following script creates a single-column clustered table containing the integers from 1 to 1,000 inclusive. IF OBJECT_ID(N'tempdb..#Test', N'U') IS NOT NULL DROP TABLE #Test ; GO CREATE TABLE #Test ( id INTEGER PRIMARY KEY CLUSTERED ); ; INSERT #Test (id) SELECT V.number FROM master.dbo.spt_values AS V WHERE V.[type] = N'P' AND V.number BETWEEN 1 AND 1000 ; Let’s say we need to find the rows with values from 100 to 170, excluding any values that divide exactly by 10.  One way to write that query would be: SELECT T.id FROM #Test AS T WHERE T.id IN ( 101,102,103,104,105,106,107,108,109, 111,112,113,114,115,116,117,118,119, 121,122,123,124,125,126,127,128,129, 131,132,133,134,135,136,137,138,139, 141,142,143,144,145,146,147,148,149, 151,152,153,154,155,156,157,158,159, 161,162,163,164,165,166,167,168,169 ) ; That query produces a pretty efficient-looking query plan: Knowing that the source column is defined as an INTEGER, we could also express the query this way: SELECT T.id FROM #Test AS T WHERE T.id >= 101 AND T.id <= 169 AND T.id % 10 > 0 ; We get a similar-looking plan: If you look closely, you might notice that the line connecting the two icons is a little thinner than before.  The first query is estimated to produce 61.9167 rows – very close to the 63 rows we know the query will return.  The second query presents a tougher challenge for SQL Server because it doesn’t know how to predict the selectivity of the modulo expression (T.id % 10 > 0).  Without that last line, the second query is estimated to produce 68.1667 rows – a slight overestimate.  Adding the opaque modulo expression results in SQL Server guessing at the selectivity.  As you may know, the selectivity guess for a greater-than operation is 30%, so the final estimate is 30% of 68.1667, which comes to 20.45 rows. The second difference is that the Clustered Index Seek is costed at 99% of the estimated total for the statement.  For some reason, the final SELECT operator is assigned a small cost of 0.0000484 units; I have absolutely no idea why this is so, or what it models.  Nevertheless, we can compare the total cost for both queries: the first one comes in at 0.0033501 units, and the second at 0.0034054.  The important point is that the second query is costed very slightly higher than the first, even though it is expected to produce many fewer rows (20.45 versus 61.9167). If you run the two queries, they produce exactly the same results, and both complete so quickly that it is impossible to measure CPU usage for a single execution.  We can, however, compare the I/O statistics for a single run by running the queries with STATISTICS IO ON: Table '#Test'. Scan count 63, logical reads 126, physical reads 0. Table '#Test'. Scan count 01, logical reads 002, physical reads 0. The query with the IN list uses 126 logical reads (and has a ‘scan count’ of 63), while the second query form completes with just 2 logical reads (and a ‘scan count’ of 1).  It is no coincidence that 126 = 63 * 2, by the way.  It is almost as if the first query is doing 63 seeks, compared to one for the second query. In fact, that is exactly what it is doing.  There is no indication of this in the graphical plan, or the tool-tip that appears when you hover your mouse over the Clustered Index Seek icon.  To see the 63 seek operations, you have click on the Seek icon and look in the Properties window (press F4, or right-click and choose from the menu): The Seek Predicates list shows a total of 63 seek operations – one for each of the values from the IN list contained in the first query.  I have expanded the first seek node to show the details; it is seeking down the clustered index to find the entry with the value 101.  Each of the other 62 nodes expands similarly, and the same information is contained (even more verbosely) in the XML form of the plan. Each of the 63 seek operations starts at the root of the clustered index B-tree and navigates down to the leaf page that contains the sought key value.  Our table is just large enough to need a separate root page, so each seek incurs 2 logical reads (one for the root, and one for the leaf).  We can see the index depth using the INDEXPROPERTY function, or by using the a DMV: SELECT S.index_type_desc, S.index_depth FROM sys.dm_db_index_physical_stats ( DB_ID(N'tempdb'), OBJECT_ID(N'tempdb..#Test', N'U'), 1, 1, DEFAULT ) AS S ; Let’s look now at the Properties window when the Clustered Index Seek from the second query is selected: There is just one seek operation, which starts at the root of the index and navigates the B-tree looking for the first key that matches the Start range condition (id >= 101).  It then continues to read records at the leaf level of the index (following links between leaf-level pages if necessary) until it finds a row that does not meet the End range condition (id <= 169).  Every row that meets the seek range condition is also tested against the Residual Predicate highlighted above (id % 10 > 0), and is only returned if it matches that as well. You will not be surprised that the single seek (with a range scan and residual predicate) is much more efficient than 63 singleton seeks.  It is not 63 times more efficient (as the logical reads comparison would suggest), but it is around three times faster.  Let’s run both query forms 10,000 times and measure the elapsed time: DECLARE @i INTEGER, @n INTEGER = 10000, @s DATETIME = GETDATE() ; SET NOCOUNT ON; SET STATISTICS XML OFF; ; WHILE @n > 0 BEGIN SELECT @i = T.id FROM #Test AS T WHERE T.id IN ( 101,102,103,104,105,106,107,108,109, 111,112,113,114,115,116,117,118,119, 121,122,123,124,125,126,127,128,129, 131,132,133,134,135,136,137,138,139, 141,142,143,144,145,146,147,148,149, 151,152,153,154,155,156,157,158,159, 161,162,163,164,165,166,167,168,169 ) ; SET @n -= 1; END ; PRINT DATEDIFF(MILLISECOND, @s, GETDATE()) ; GO DECLARE @i INTEGER, @n INTEGER = 10000, @s DATETIME = GETDATE() ; SET NOCOUNT ON ; WHILE @n > 0 BEGIN SELECT @i = T.id FROM #Test AS T WHERE T.id >= 101 AND T.id <= 169 AND T.id % 10 > 0 ; SET @n -= 1; END ; PRINT DATEDIFF(MILLISECOND, @s, GETDATE()) ; On my laptop, running SQL Server 2008 build 4272 (SP2 CU2), the IN form of the query takes around 830ms and the range query about 300ms.  The main point of this post is not performance, however – it is meant as an introduction to the next few parts in this mini-series that will continue to explore scans and seeks in detail. When is a seek not a seek?  When it is 63 seeks © Paul White 2011 email: [email protected] twitter: @SQL_kiwi

    Read the article

  • Fun with Aggregates

    - by Paul White
    There are interesting things to be learned from even the simplest queries.  For example, imagine you are given the task of writing a query to list AdventureWorks product names where the product has at least one entry in the transaction history table, but fewer than ten. One possible query to meet that specification is: SELECT p.Name FROM Production.Product AS p JOIN Production.TransactionHistory AS th ON p.ProductID = th.ProductID GROUP BY p.ProductID, p.Name HAVING COUNT_BIG(*) < 10; That query correctly returns 23 rows (execution plan and data sample shown below): The execution plan looks a bit different from the written form of the query: the base tables are accessed in reverse order, and the aggregation is performed before the join.  The general idea is to read all rows from the history table, compute the count of rows grouped by ProductID, merge join the results to the Product table on ProductID, and finally filter to only return rows where the count is less than ten. This ‘fully-optimized’ plan has an estimated cost of around 0.33 units.  The reason for the quote marks there is that this plan is not quite as optimal as it could be – surely it would make sense to push the Filter down past the join too?  To answer that, let’s look at some other ways to formulate this query.  This being SQL, there are any number of ways to write logically-equivalent query specifications, so we’ll just look at a couple of interesting ones.  The first query is an attempt to reverse-engineer T-SQL from the optimized query plan shown above.  It joins the result of pre-aggregating the history table to the Product table before filtering: SELECT p.Name FROM ( SELECT th.ProductID, cnt = COUNT_BIG(*) FROM Production.TransactionHistory AS th GROUP BY th.ProductID ) AS q1 JOIN Production.Product AS p ON p.ProductID = q1.ProductID WHERE q1.cnt < 10; Perhaps a little surprisingly, we get a slightly different execution plan: The results are the same (23 rows) but this time the Filter is pushed below the join!  The optimizer chooses nested loops for the join, because the cardinality estimate for rows passing the Filter is a bit low (estimate 1 versus 23 actual), though you can force a merge join with a hint and the Filter still appears below the join.  In yet another variation, the < 10 predicate can be ‘manually pushed’ by specifying it in a HAVING clause in the “q1” sub-query instead of in the WHERE clause as written above. The reason this predicate can be pushed past the join in this query form, but not in the original formulation is simply an optimizer limitation – it does make efforts (primarily during the simplification phase) to encourage logically-equivalent query specifications to produce the same execution plan, but the implementation is not completely comprehensive. Moving on to a second example, the following query specification results from phrasing the requirement as “list the products where there exists fewer than ten correlated rows in the history table”: SELECT p.Name FROM Production.Product AS p WHERE EXISTS ( SELECT * FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID HAVING COUNT_BIG(*) < 10 ); Unfortunately, this query produces an incorrect result (86 rows): The problem is that it lists products with no history rows, though the reasons are interesting.  The COUNT_BIG(*) in the EXISTS clause is a scalar aggregate (meaning there is no GROUP BY clause) and scalar aggregates always produce a value, even when the input is an empty set.  In the case of the COUNT aggregate, the result of aggregating the empty set is zero (the other standard aggregates produce a NULL).  To make the point really clear, let’s look at product 709, which happens to be one for which no history rows exist: -- Scalar aggregate SELECT COUNT_BIG(*) FROM Production.TransactionHistory AS th WHERE th.ProductID = 709;   -- Vector aggregate SELECT COUNT_BIG(*) FROM Production.TransactionHistory AS th WHERE th.ProductID = 709 GROUP BY th.ProductID; The estimated execution plans for these two statements are almost identical: You might expect the Stream Aggregate to have a Group By for the second statement, but this is not the case.  The query includes an equality comparison to a constant value (709), so all qualified rows are guaranteed to have the same value for ProductID and the Group By is optimized away. In fact there are some minor differences between the two plans (the first is auto-parameterized and qualifies for trivial plan, whereas the second is not auto-parameterized and requires cost-based optimization), but there is nothing to indicate that one is a scalar aggregate and the other is a vector aggregate.  This is something I would like to see exposed in show plan so I suggested it on Connect.  Anyway, the results of running the two queries show the difference at runtime: The scalar aggregate (no GROUP BY) returns a result of zero, whereas the vector aggregate (with a GROUP BY clause) returns nothing at all.  Returning to our EXISTS query, we could ‘fix’ it by changing the HAVING clause to reject rows where the scalar aggregate returns zero: SELECT p.Name FROM Production.Product AS p WHERE EXISTS ( SELECT * FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID HAVING COUNT_BIG(*) BETWEEN 1 AND 9 ); The query now returns the correct 23 rows: Unfortunately, the execution plan is less efficient now – it has an estimated cost of 0.78 compared to 0.33 for the earlier plans.  Let’s try adding a redundant GROUP BY instead of changing the HAVING clause: SELECT p.Name FROM Production.Product AS p WHERE EXISTS ( SELECT * FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID GROUP BY th.ProductID HAVING COUNT_BIG(*) < 10 ); Not only do we now get correct results (23 rows), this is the execution plan: I like to compare that plan to quantum physics: if you don’t find it shocking, you haven’t understood it properly :)  The simple addition of a redundant GROUP BY has resulted in the EXISTS form of the query being transformed into exactly the same optimal plan we found earlier.  What’s more, in SQL Server 2008 and later, we can replace the odd-looking GROUP BY with an explicit GROUP BY on the empty set: SELECT p.Name FROM Production.Product AS p WHERE EXISTS ( SELECT * FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID GROUP BY () HAVING COUNT_BIG(*) < 10 ); I offer that as an alternative because some people find it more intuitive (and it perhaps has more geek value too).  Whichever way you prefer, it’s rather satisfying to note that the result of the sub-query does not exist for a particular correlated value where a vector aggregate is used (the scalar COUNT aggregate always returns a value, even if zero, so it always ‘EXISTS’ regardless which ProductID is logically being evaluated). The following query forms also produce the optimal plan and correct results, so long as a vector aggregate is used (you can probably find more equivalent query forms): WHERE Clause SELECT p.Name FROM Production.Product AS p WHERE ( SELECT COUNT_BIG(*) FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID GROUP BY () ) < 10; APPLY SELECT p.Name FROM Production.Product AS p CROSS APPLY ( SELECT NULL FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID GROUP BY () HAVING COUNT_BIG(*) < 10 ) AS ca (dummy); FROM Clause SELECT q1.Name FROM ( SELECT p.Name, cnt = ( SELECT COUNT_BIG(*) FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID GROUP BY () ) FROM Production.Product AS p ) AS q1 WHERE q1.cnt < 10; This last example uses SUM(1) instead of COUNT and does not require a vector aggregate…you should be able to work out why :) SELECT q.Name FROM ( SELECT p.Name, cnt = ( SELECT SUM(1) FROM Production.TransactionHistory AS th WHERE th.ProductID = p.ProductID ) FROM Production.Product AS p ) AS q WHERE q.cnt < 10; The semantics of SQL aggregates are rather odd in places.  It definitely pays to get to know the rules, and to be careful to check whether your queries are using scalar or vector aggregates.  As we have seen, query plans do not show in which ‘mode’ an aggregate is running and getting it wrong can cause poor performance, wrong results, or both. © 2012 Paul White Twitter: @SQL_Kiwi email: [email protected]

    Read the article

  • 12.10 does not boot sometimes from the hard drive, but it does consistently from the CD

    - by Robert
    I have recently switched from Windows 7 to Ubuntu 12.10. I have installed Ubuntu 12.10 and I cleared everything from my computer, but it randomly stops at different screens. Only a purple screen comes up. I can choose Ubuntu from a list and a blinking white dot appears in the top left corner. The previous things happen and the Ubuntu login screen appears an I can log in. It is random. and I have not changed anything. I can always insert the bootable CD and it will work every time.

    Read the article

  • Ubuntu 12.10 installation. Hit or miss Booting

    - by Robert
    I just recently downloaded and installed Ubuntu 12.10. I also completely wiped the laptop. The Ubuntu OS will only boot part of the time but never on the first time. Always, the first start up will automatically go to a purple screen and stay there. At first I waited for 45 minutes and nothing changed. Once I held down the power button to turn it off, I turned it back on to see the Asus screen followed by the grub menu. I can select "Ubuntu" and then there is a white box blinking in the top left corner. Then, it will either keep blinking or transfer to the Ubuntu loading screen(everything works fine if it gets to the loading screen). This has never happened before with prior versions of Ubuntu. Any ideas are helpful. Thanks!

    Read the article

< Previous Page | 12 13 14 15 16 17 18 19 20 21 22 23  | Next Page >