Search Results

Search found 8267 results on 331 pages for 'mark white'.

Page 25/331 | < Previous Page | 21 22 23 24 25 26 27 28 29 30 31 32  | Next Page >

  • top tweets SOA Partner Community – June 2013

    - by JuergenKress
    Send your tweets @soacommunity #soacommunity and follow us at http://twitter.com/soacommunity Oracle SOA Learn how Business Rules are used in Oracle SOA Suite. New free self-study course - Oracle Univ. #soa #oraclesoa http://pub.vitrue.com/ll9B OPITZ CONSULTING ?Wie #BPM und #SOA zusammengehören? Watch 100-Seconds-Video-Lesson by @Rolfbaer - http://ow.ly/luSjK @soacommunity Andrejus Baranovskis ?Customized BPM 11g PS6 Workspace Application http://fb.me/2ukaSBXKs Mark Nelson ?Case Management Samples Released http://wp.me/pgVeO-Lv Mark Nelson Instance Patching Demo for BPM 11.1.1.7 http://wp.me/pgVeO-Lx Simone Geib Antony Reynolds: Target Verification #oraclesoa https://blogs.oracle.com/reynolds/ OPITZ CONSULTING ?"It's all about Integration - Developing with Oracle #Cloud Services" @t_winterberg files: http://ow.ly/ljtEY #cloudworld @soacommunity Arun Pareek ?Functional Testing Business Processes In Oracle BPM Suite 11g http://wp.me/pkPu1-pc via @arrunpareek SOA Proactive Want to get started with Human Workflow? Check out the introductory video on OTN, http://pub.vitrue.com/enIL C2B2 Consulting Free tech workshop,London 6th of Jun Diagnosing Performance & Scalability Problems in Oracle SOASuite http://www.c2b2.co.uk/oracle_fusion_middleware_performance_seminar … @soacommunity Oracle BPM Must have technologies for delivering effective #CX : #BPM #Social #Mobile > #OracleBPM Whitepaper http://pub.vitrue.com/6pF6 OracleBlogs ?Introduction to Web Forms -Basic Tutorial http://ow.ly/2wQLTE OTNArchBeat ?Complete State of SOA podcast now available w/ @soacommunity @hajonormann @gschmutz @t_winterberg #industrialsoa http://pub.vitrue.com/PZFw Ronald Luttikhuizen VENNSTER Blog | Article published - Fault Handling and Prevention - Part 2 | http://blog.vennster.nl/2013/05/article-published-fault-handling-and.html … Mark Nelson ?Getting to know Maven http://wp.me/pgVeO-Lk gschmutz ?Cool! Our 2nd article has just been published: "Fault Handling and Prevention for Services in Oracle Service Bus" http://pub.vitrue.com/jMOy David Shaffer Interesting SOA Development and Delivery post on A-Team Redstack site - http://bit.ly/18oqrAI . Would be great to get others to contribute! Mark Nelson BPM PS6 video showing process lifecycle in more detail (30min) http://wp.me/pgVeO-Ko SOA Proactive ?Webcast: 'Introduction and Troubleshooting of the SOA 11g Database Adapter', May 9th. Register now at http://pub.vitrue.com/8In7 Mark Nelson ?SOA Development and Delivery http://wp.me/pgVeO-Kd Oracle BPM Manoj Das, VP Product Mangement talks about new #OracleBPM release #BPM #processmanagement http://pub.vitrue.com/FV3R OTNArchBeat Podcast: The State of SOA w/ @soacommunity @hajonormann @gschmutz @t_winterberg #industrialsoa http://pub.vitrue.com/OK2M gschmutz New article series on Industrial SOA started on OTN and Service Technology Magazine: http://guidoschmutz.wordpress.com/2013/04/22/first-two-chapters-of-industrial-soa-articles-series-have-been-published-both-on-otn-and-service-technology-magazine/ … #industrialSOA Danilo Schmiedel ?Article series #industrialSOA published on OTN and Service Technology Magazine http://inside-bpm-and-soa.blogspot.de/2013/04/industrial-soa_22.html … @soacommunity @OC_WIRE SOA & BPM Partner Community For regular information on Oracle SOA Suite become a member in the SOA & BPM Partner Community for registration please visit www.oracle.com/goto/emea/soa (OPN account required) If you need support with your account please contact the Oracle Partner Business Center. Blog Twitter LinkedIn Facebook Wiki Mix Forum Technorati Tags: twitter,SOA Community,Oracle SOA,Oracle BPM,Community,OPN,Jürgen Kress

    Read the article

  • OBI & P6 Analytics Demo @ MAOAUG

    - by mark.kromer
    Mark will be speaking in King of Prussia, outside of Philly, for the Mid-Atlantic Oracle Apps Users Group on Oracle BI w/P6 Analytics for IT projects this Friday: http://www.maoaug.org. Stop by and say HI if you are in the area!

    Read the article

  • Free Live Webinar on Oracle Primavera P6 Analytics

    - by mark.kromer
    We are having a free live webinar to introduce customers to the new Oracle Primavera P6 Analytics built on the Oracle Business Intelligence platform. Here is the registration link for this webinar which is on June 18 @ 2 PM EDT: https://event.on24.com/eventRegistration/EventLobbyServlet?target=registration.jsp&eventid=209488&sessionid=1&key=DC3994754137CE4292161B2041C0E35D&partnerref=homepagebanner Hope to see you there! Best, Mark

    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

  • Where is all the memory being consumed?

    - by Mark L
    Hello, I have a Dell R300 Ubuntu 9.10 box with 4GB of memory. All I'm running on there is haproxy, nagios and postfix yet there is ~2.7GB of memory being consumed. I've run ps and I can't get the sums to add up. Could anyone shed any light on where all the memory is being used? Cheers, Mark $ sudo free -m total used free shared buffers cached Mem: 3957 2746 1211 0 169 2320 -/+ buffers/cache: 256 3701 Swap: 6212 0 6212 Sorry for pasting all of ps' output but I'm keen to get to the bottom of this. $ sudo ps aux [sudo] password for mark: USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 19320 1656 ? Ss May20 0:05 /sbin/init root 2 0.0 0.0 0 0 ? S< May20 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S< May20 0:00 [migration/0] root 4 0.0 0.0 0 0 ? S< May20 0:16 [ksoftirqd/0] root 5 0.0 0.0 0 0 ? S< May20 0:00 [watchdog/0] root 6 0.0 0.0 0 0 ? S< May20 0:03 [migration/1] root 7 0.0 0.0 0 0 ? S< May20 3:10 [ksoftirqd/1] root 8 0.0 0.0 0 0 ? S< May20 0:00 [watchdog/1] root 9 0.0 0.0 0 0 ? S< May20 0:00 [migration/2] root 10 0.0 0.0 0 0 ? S< May20 0:19 [ksoftirqd/2] root 11 0.0 0.0 0 0 ? S< May20 0:00 [watchdog/2] root 12 0.0 0.0 0 0 ? S< May20 0:01 [migration/3] root 13 0.0 0.0 0 0 ? S< May20 0:41 [ksoftirqd/3] root 14 0.0 0.0 0 0 ? S< May20 0:00 [watchdog/3] root 15 0.0 0.0 0 0 ? S< May20 0:03 [events/0] root 16 0.0 0.0 0 0 ? S< May20 0:10 [events/1] root 17 0.0 0.0 0 0 ? S< May20 0:08 [events/2] root 18 0.0 0.0 0 0 ? S< May20 0:08 [events/3] root 19 0.0 0.0 0 0 ? S< May20 0:00 [cpuset] root 20 0.0 0.0 0 0 ? S< May20 0:00 [khelper] root 21 0.0 0.0 0 0 ? S< May20 0:00 [netns] root 22 0.0 0.0 0 0 ? S< May20 0:00 [async/mgr] root 23 0.0 0.0 0 0 ? S< May20 0:00 [kintegrityd/0] root 24 0.0 0.0 0 0 ? S< May20 0:00 [kintegrityd/1] root 25 0.0 0.0 0 0 ? S< May20 0:00 [kintegrityd/2] root 26 0.0 0.0 0 0 ? S< May20 0:00 [kintegrityd/3] root 27 0.0 0.0 0 0 ? S< May20 0:00 [kblockd/0] root 28 0.0 0.0 0 0 ? S< May20 0:01 [kblockd/1] root 29 0.0 0.0 0 0 ? S< May20 0:04 [kblockd/2] root 30 0.0 0.0 0 0 ? S< May20 0:02 [kblockd/3] root 31 0.0 0.0 0 0 ? S< May20 0:00 [kacpid] root 32 0.0 0.0 0 0 ? S< May20 0:00 [kacpi_notify] root 33 0.0 0.0 0 0 ? S< May20 0:00 [kacpi_hotplug] root 34 0.0 0.0 0 0 ? S< May20 0:00 [ata/0] root 35 0.0 0.0 0 0 ? S< May20 0:00 [ata/1] root 36 0.0 0.0 0 0 ? S< May20 0:00 [ata/2] root 37 0.0 0.0 0 0 ? S< May20 0:00 [ata/3] root 38 0.0 0.0 0 0 ? S< May20 0:00 [ata_aux] root 39 0.0 0.0 0 0 ? S< May20 0:00 [ksuspend_usbd] root 40 0.0 0.0 0 0 ? S< May20 0:00 [khubd] root 41 0.0 0.0 0 0 ? S< May20 0:00 [kseriod] root 42 0.0 0.0 0 0 ? S< May20 0:00 [kmmcd] root 43 0.0 0.0 0 0 ? S< May20 0:00 [bluetooth] root 44 0.0 0.0 0 0 ? S May20 0:00 [khungtaskd] root 45 0.0 0.0 0 0 ? S May20 0:00 [pdflush] root 46 0.0 0.0 0 0 ? S May20 0:09 [pdflush] root 47 0.0 0.0 0 0 ? S< May20 0:00 [kswapd0] root 48 0.0 0.0 0 0 ? S< May20 0:00 [aio/0] root 49 0.0 0.0 0 0 ? S< May20 0:00 [aio/1] root 50 0.0 0.0 0 0 ? S< May20 0:00 [aio/2] root 51 0.0 0.0 0 0 ? S< May20 0:00 [aio/3] root 52 0.0 0.0 0 0 ? S< May20 0:00 [ecryptfs-kthrea] root 53 0.0 0.0 0 0 ? S< May20 0:00 [crypto/0] root 54 0.0 0.0 0 0 ? S< May20 0:00 [crypto/1] root 55 0.0 0.0 0 0 ? S< May20 0:00 [crypto/2] root 56 0.0 0.0 0 0 ? S< May20 0:00 [crypto/3] root 70 0.0 0.0 0 0 ? S< May20 0:00 [scsi_eh_0] root 71 0.0 0.0 0 0 ? S< May20 0:00 [scsi_eh_1] root 74 0.0 0.0 0 0 ? S< May20 0:00 [scsi_eh_2] root 75 0.0 0.0 0 0 ? S< May20 0:00 [scsi_eh_3] root 82 0.0 0.0 0 0 ? S< May20 0:00 [kstriped] root 83 0.0 0.0 0 0 ? S< May20 0:00 [kmpathd/0] root 84 0.0 0.0 0 0 ? S< May20 0:00 [kmpathd/1] root 85 0.0 0.0 0 0 ? S< May20 0:00 [kmpathd/2] root 86 0.0 0.0 0 0 ? S< May20 0:00 [kmpathd/3] root 87 0.0 0.0 0 0 ? S< May20 0:00 [kmpath_handlerd] root 88 0.0 0.0 0 0 ? S< May20 0:00 [ksnapd] root 89 0.0 0.0 0 0 ? S< May20 0:00 [kondemand/0] root 90 0.0 0.0 0 0 ? S< May20 0:00 [kondemand/1] root 91 0.0 0.0 0 0 ? S< May20 0:00 [kondemand/2] root 92 0.0 0.0 0 0 ? S< May20 0:00 [kondemand/3] root 93 0.0 0.0 0 0 ? S< May20 0:00 [kconservative/0] root 94 0.0 0.0 0 0 ? S< May20 0:00 [kconservative/1] root 95 0.0 0.0 0 0 ? S< May20 0:00 [kconservative/2] root 96 0.0 0.0 0 0 ? S< May20 0:00 [kconservative/3] root 97 0.0 0.0 0 0 ? S< May20 0:00 [krfcommd] root 315 0.0 0.0 0 0 ? S< May20 0:09 [mpt_poll_0] root 317 0.0 0.0 0 0 ? S< May20 0:00 [mpt/0] root 547 0.0 0.0 0 0 ? S< May20 0:00 [scsi_eh_4] root 587 0.0 0.0 0 0 ? S< May20 0:11 [kjournald2] root 636 0.0 0.0 12748 860 ? S May20 0:00 upstart-udev-bridge --daemon root 657 0.0 0.0 17064 924 ? S<s May20 0:00 udevd --daemon root 666 0.0 0.0 8192 612 ? Ss May20 0:00 dd bs=1 if=/proc/kmsg of=/var/run/rsyslog/kmsg root 774 0.0 0.0 17060 888 ? S< May20 0:00 udevd --daemon root 775 0.0 0.0 17060 888 ? S< May20 0:00 udevd --daemon syslog 825 0.0 0.0 191696 1988 ? Sl May20 0:31 rsyslogd -c4 root 839 0.0 0.0 0 0 ? S< May20 0:00 [edac-poller] root 870 0.0 0.0 0 0 ? S< May20 0:00 [kpsmoused] root 1006 0.0 0.0 5988 604 tty4 Ss+ May20 0:00 /sbin/getty -8 38400 tty4 root 1008 0.0 0.0 5988 604 tty5 Ss+ May20 0:00 /sbin/getty -8 38400 tty5 root 1015 0.0 0.0 5988 604 tty2 Ss+ May20 0:00 /sbin/getty -8 38400 tty2 root 1016 0.0 0.0 5988 608 tty3 Ss+ May20 0:00 /sbin/getty -8 38400 tty3 root 1018 0.0 0.0 5988 604 tty6 Ss+ May20 0:00 /sbin/getty -8 38400 tty6 daemon 1025 0.0 0.0 16512 472 ? Ss May20 0:00 atd root 1026 0.0 0.0 18708 1000 ? Ss May20 0:03 cron root 1052 0.0 0.0 49072 1252 ? Ss May20 0:25 /usr/sbin/sshd root 1084 0.0 0.0 5988 604 tty1 Ss+ May20 0:00 /sbin/getty -8 38400 tty1 root 6320 0.0 0.0 19440 956 ? Ss May21 0:00 /usr/sbin/xinetd -pidfile /var/run/xinetd.pid -stayalive -inetd_compat -inetd_ipv6 nagios 8197 0.0 0.0 27452 1696 ? SNs May21 2:57 /usr/sbin/nagios3 -d /etc/nagios3/nagios.cfg root 10882 0.1 0.0 70280 3104 ? Ss 10:30 0:00 sshd: mark [priv] mark 10934 0.0 0.0 70432 1776 ? S 10:30 0:00 sshd: mark@pts/0 mark 10935 1.4 0.1 21572 4336 pts/0 Ss 10:30 0:00 -bash root 10953 1.0 0.0 15164 1136 pts/0 R+ 10:30 0:00 ps aux haproxy 12738 0.0 0.0 17208 992 ? Ss Jun08 0:49 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg root 23953 0.0 0.0 37012 2192 ? Ss Jun04 0:03 /usr/lib/postfix/master postfix 23955 0.0 0.0 39232 2356 ? S Jun04 0:00 qmgr -l -t fifo -u postfix 32603 0.0 0.0 39072 2132 ? S 09:05 0:00 pickup -l -t fifo -u -c Here's meminfo: $ cat /proc/meminfo MemTotal: 4052852 kB MemFree: 1240488 kB Buffers: 173172 kB Cached: 2376420 kB SwapCached: 0 kB Active: 1479288 kB Inactive: 1081876 kB Active(anon): 11792 kB Inactive(anon): 0 kB Active(file): 1467496 kB Inactive(file): 1081876 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 6361700 kB SwapFree: 6361700 kB Dirty: 44 kB Writeback: 0 kB AnonPages: 11568 kB Mapped: 5844 kB Slab: 155032 kB SReclaimable: 145804 kB SUnreclaim: 9228 kB PageTables: 1592 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 8388124 kB Committed_AS: 51732 kB VmallocTotal: 34359738367 kB VmallocUsed: 282604 kB VmallocChunk: 34359453499 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 6784 kB DirectMap2M: 4182016 kB Here's slabinfo: $ cat /proc/slabinfo slabinfo - version: 2.1 # name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail> ip6_dst_cache 50 50 320 25 2 : tunables 0 0 0 : slabdata 2 2 0 UDPLITEv6 0 0 960 17 4 : tunables 0 0 0 : slabdata 0 0 0 UDPv6 68 68 960 17 4 : tunables 0 0 0 : slabdata 4 4 0 tw_sock_TCPv6 0 0 320 25 2 : tunables 0 0 0 : slabdata 0 0 0 TCPv6 72 72 1792 18 8 : tunables 0 0 0 : slabdata 4 4 0 dm_raid1_read_record 0 0 1064 30 8 : tunables 0 0 0 : slabdata 0 0 0 kcopyd_job 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 dm_uevent 0 0 2608 12 8 : tunables 0 0 0 : slabdata 0 0 0 dm_rq_target_io 0 0 376 21 2 : tunables 0 0 0 : slabdata 0 0 0 uhci_urb_priv 0 0 56 73 1 : tunables 0 0 0 : slabdata 0 0 0 cfq_queue 0 0 168 24 1 : tunables 0 0 0 : slabdata 0 0 0 mqueue_inode_cache 18 18 896 18 4 : tunables 0 0 0 : slabdata 1 1 0 fuse_request 0 0 632 25 4 : tunables 0 0 0 : slabdata 0 0 0 fuse_inode 0 0 768 21 4 : tunables 0 0 0 : slabdata 0 0 0 ecryptfs_inode_cache 0 0 1024 16 4 : tunables 0 0 0 : slabdata 0 0 0 hugetlbfs_inode_cache 26 26 608 26 4 : tunables 0 0 0 : slabdata 1 1 0 journal_handle 680 680 24 170 1 : tunables 0 0 0 : slabdata 4 4 0 journal_head 144 144 112 36 1 : tunables 0 0 0 : slabdata 4 4 0 revoke_table 256 256 16 256 1 : tunables 0 0 0 : slabdata 1 1 0 revoke_record 512 512 32 128 1 : tunables 0 0 0 : slabdata 4 4 0 ext4_inode_cache 53306 53424 888 18 4 : tunables 0 0 0 : slabdata 2968 2968 0 ext4_free_block_extents 292 292 56 73 1 : tunables 0 0 0 : slabdata 4 4 0 ext4_alloc_context 112 112 144 28 1 : tunables 0 0 0 : slabdata 4 4 0 ext4_prealloc_space 156 156 104 39 1 : tunables 0 0 0 : slabdata 4 4 0 ext4_system_zone 0 0 40 102 1 : tunables 0 0 0 : slabdata 0 0 0 ext2_inode_cache 0 0 776 21 4 : tunables 0 0 0 : slabdata 0 0 0 ext3_inode_cache 0 0 784 20 4 : tunables 0 0 0 : slabdata 0 0 0 ext3_xattr 0 0 88 46 1 : tunables 0 0 0 : slabdata 0 0 0 dquot 0 0 256 16 1 : tunables 0 0 0 : slabdata 0 0 0 shmem_inode_cache 606 620 800 20 4 : tunables 0 0 0 : slabdata 31 31 0 pid_namespace 0 0 2112 15 8 : tunables 0 0 0 : slabdata 0 0 0 UDP-Lite 0 0 832 19 4 : tunables 0 0 0 : slabdata 0 0 0 RAW 183 210 768 21 4 : tunables 0 0 0 : slabdata 10 10 0 UDP 76 76 832 19 4 : tunables 0 0 0 : slabdata 4 4 0 tw_sock_TCP 80 80 256 16 1 : tunables 0 0 0 : slabdata 5 5 0 TCP 81 114 1664 19 8 : tunables 0 0 0 : slabdata 6 6 0 blkdev_integrity 144 144 112 36 1 : tunables 0 0 0 : slabdata 4 4 0 blkdev_queue 64 64 2024 16 8 : tunables 0 0 0 : slabdata 4 4 0 blkdev_requests 120 120 336 24 2 : tunables 0 0 0 : slabdata 5 5 0 fsnotify_event 156 156 104 39 1 : tunables 0 0 0 : slabdata 4 4 0 bip-256 7 7 4224 7 8 : tunables 0 0 0 : slabdata 1 1 0 bip-128 0 0 2176 15 8 : tunables 0 0 0 : slabdata 0 0 0 bip-64 0 0 1152 28 8 : tunables 0 0 0 : slabdata 0 0 0 bip-16 84 84 384 21 2 : tunables 0 0 0 : slabdata 4 4 0 sock_inode_cache 224 276 704 23 4 : tunables 0 0 0 : slabdata 12 12 0 file_lock_cache 88 88 184 22 1 : tunables 0 0 0 : slabdata 4 4 0 net_namespace 0 0 1920 17 8 : tunables 0 0 0 : slabdata 0 0 0 Acpi-ParseExt 640 672 72 56 1 : tunables 0 0 0 : slabdata 12 12 0 taskstats 48 48 328 24 2 : tunables 0 0 0 : slabdata 2 2 0 proc_inode_cache 1613 1750 640 25 4 : tunables 0 0 0 : slabdata 70 70 0 sigqueue 100 100 160 25 1 : tunables 0 0 0 : slabdata 4 4 0 radix_tree_node 22443 22475 560 29 4 : tunables 0 0 0 : slabdata 775 775 0 bdev_cache 72 72 896 18 4 : tunables 0 0 0 : slabdata 4 4 0 sysfs_dir_cache 9866 9894 80 51 1 : tunables 0 0 0 : slabdata 194 194 0 inode_cache 2268 2268 592 27 4 : tunables 0 0 0 : slabdata 84 84 0 dentry 285907 286062 192 21 1 : tunables 0 0 0 : slabdata 13622 13622 0 buffer_head 256447 257472 112 36 1 : tunables 0 0 0 : slabdata 7152 7152 0 vm_area_struct 1469 1541 176 23 1 : tunables 0 0 0 : slabdata 67 67 0 mm_struct 82 95 832 19 4 : tunables 0 0 0 : slabdata 5 5 0 files_cache 104 161 704 23 4 : tunables 0 0 0 : slabdata 7 7 0 signal_cache 163 187 960 17 4 : tunables 0 0 0 : slabdata 11 11 0 sighand_cache 145 165 2112 15 8 : tunables 0 0 0 : slabdata 11 11 0 task_xstate 118 140 576 28 4 : tunables 0 0 0 : slabdata 5 5 0 task_struct 128 165 5808 5 8 : tunables 0 0 0 : slabdata 33 33 0 anon_vma 731 896 32 128 1 : tunables 0 0 0 : slabdata 7 7 0 shared_policy_node 85 85 48 85 1 : tunables 0 0 0 : slabdata 1 1 0 numa_policy 170 170 24 170 1 : tunables 0 0 0 : slabdata 1 1 0 idr_layer_cache 240 240 544 30 4 : tunables 0 0 0 : slabdata 8 8 0 kmalloc-8192 27 32 8192 4 8 : tunables 0 0 0 : slabdata 8 8 0 kmalloc-4096 291 344 4096 8 8 : tunables 0 0 0 : slabdata 43 43 0 kmalloc-2048 225 240 2048 16 8 : tunables 0 0 0 : slabdata 15 15 0 kmalloc-1024 366 432 1024 16 4 : tunables 0 0 0 : slabdata 27 27 0 kmalloc-512 536 544 512 16 2 : tunables 0 0 0 : slabdata 34 34 0 kmalloc-256 406 528 256 16 1 : tunables 0 0 0 : slabdata 33 33 0 kmalloc-128 503 576 128 32 1 : tunables 0 0 0 : slabdata 18 18 0 kmalloc-64 3467 3712 64 64 1 : tunables 0 0 0 : slabdata 58 58 0 kmalloc-32 1520 1920 32 128 1 : tunables 0 0 0 : slabdata 15 15 0 kmalloc-16 3547 3840 16 256 1 : tunables 0 0 0 : slabdata 15 15 0 kmalloc-8 4607 4608 8 512 1 : tunables 0 0 0 : slabdata 9 9 0 kmalloc-192 4620 5313 192 21 1 : tunables 0 0 0 : slabdata 253 253 0 kmalloc-96 1780 1848 96 42 1 : tunables 0 0 0 : slabdata 44 44 0 kmem_cache_node 0 0 64 64 1 : tunables 0 0 0 : slabdata 0 0 0

    Read the article

  • traffic shaping for certain (local) users

    - by JMW
    Hello, i'm using ubuntu 10.10 i've a local backup user called "backup". :) i would like to give this user just a bandwidth of 1Mbit. No matter which software wants to connect to the network. this solution doesn't work: iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner 1001 -j MARK --set-mark 12 iptables -t mangle -A POSTROUTING -p tcp -m owner --uid-owner 1001 -j MARK --set-mark 12 tc qdisc del dev eth0 root tc qdisc add dev eth0 root handle 2 htb default 1 tc filter add dev eth0 parent 2: protocol ip pref 2 handle 50 fw classid 2:6 tc class add dev eth0 parent 2: classid 2:6 htb rate 10Kbit ceil 1Mbit tc qdisc show dev eth0 tc class show dev eth0 tc filter show dev eth0 does anyone know how to do it? thanks a lot in advance

    Read the article

  • SmartOS reboots spontaneously

    - by Alex
    I run a SmartOS system on a Hetzner EX4S (Intel Core i7-2600, 32G RAM, 2x3Tb SATA HDD). There are six virtual machines on the host: [root@10-bf-48-7f-e7-03 ~]# vmadm list UUID TYPE RAM STATE ALIAS d2223467-bbe5-4b81-a9d1-439e9a66d43f KVM 512 running xxxx1 5f36358f-68fa-4351-b66f-830484b9a6ee KVM 1024 running xxxx2 d570e9ac-9eac-4e4f-8fda-2b1d721c8358 OS 1024 running xxxx3 ef88979e-fb7f-460c-bf56-905755e0a399 KVM 1024 running xxxx4 d8e06def-c9c9-4d17-b975-47dd4836f962 KVM 4096 running xxxx5 4b06fe88-db6e-4cf3-aadd-e1006ada7188 KVM 9216 running xxxx5 [root@10-bf-48-7f-e7-03 ~]# The host reboots several times a week with no crash dump in /var/crash and no messages in the /var/adm/messages log. Basically /var/adm/messages looks like there was a hard reset: 2012-11-23T08:54:43.210625+00:00 10-bf-48-7f-e7-03 rsyslogd: -- MARK -- 2012-11-23T09:14:43.187589+00:00 10-bf-48-7f-e7-03 rsyslogd: -- MARK -- 2012-11-23T09:34:43.165100+00:00 10-bf-48-7f-e7-03 rsyslogd: -- MARK -- 2012-11-23T09:54:43.142065+00:00 10-bf-48-7f-e7-03 rsyslogd: -- MARK -- 2012-11-23T10:14:43.119365+00:00 10-bf-48-7f-e7-03 rsyslogd: -- MARK -- 2012-11-23T10:34:43.096351+00:00 10-bf-48-7f-e7-03 rsyslogd: -- MARK -- 2012-11-23T10:54:43.073821+00:00 10-bf-48-7f-e7-03 rsyslogd: -- MARK -- 2012-11-23T10:57:55.610954+00:00 10-bf-48-7f-e7-03 genunix: [ID 540533 kern.notice] #015SunOS Release 5.11 Version joyent_20121018T224723Z 64-bit 2012-11-23T10:57:55.610962+00:00 10-bf-48-7f-e7-03 genunix: [ID 299592 kern.notice] Copyright (c) 2010-2012, Joyent Inc. All rights reserved. 2012-11-23T10:57:55.610967+00:00 10-bf-48-7f-e7-03 unix: [ID 223955 kern.info] x86_feature: lgpg 2012-11-23T10:57:55.610971+00:00 10-bf-48-7f-e7-03 unix: [ID 223955 kern.info] x86_feature: tsc 2012-11-23T10:57:55.610974+00:00 10-bf-48-7f-e7-03 unix: [ID 223955 kern.info] x86_feature: msr 2012-11-23T10:57:55.610978+00:00 10-bf-48-7f-e7-03 unix: [ID 223955 kern.info] x86_feature: mtrr 2012-11-23T10:57:55.610981+00:00 10-bf-48-7f-e7-03 unix: [ID 223955 kern.info] x86_feature: pge 2012-11-23T10:57:55.610984+00:00 10-bf-48-7f-e7-03 unix: [ID 223955 kern.info] x86_feature: de 2012-11-23T10:57:55.610987+00:00 10-bf-48-7f-e7-03 unix: [ID 223955 kern.info] x86_feature: cmov 2012-11-23T10:57:55.610995+00:00 10-bf-48-7f-e7-03 unix: [ID 223955 kern.info] x86_feature: mmx 2012-11-23T10:57:55.611000+00:00 10-bf-48-7f-e7-03 unix: [ID 223955 kern.info] x86_feature: mca 2012-11-23T10:57:55.611004+00:00 10-bf-48-7f-e7-03 unix: [ID 223955 kern.info] x86_feature: pae 2012-11-23T10:57:55.611008+00:00 10-bf-48-7f-e7-03 unix: [ID 223955 kern.info] x86_feature: cv8 The problem is that sometimes the host loses the network interface on reboot so we need to perform a manual hardware reset to bring it back. We do not have physical or virtual access to the server console - no KVM, no iLO or anything like this. So, the only way to debug is to analyze crash dumps/log files. I am not a SmartOS/Solaris expert so I am not sure how to proceed. Is there any equivalent of Linux netconsole for SmartOS? Can I just redirect the console output to the network port somehow? Maybe I am missing something obvious and crash information is located somewhere else.

    Read the article

  • Ms Excel 2010 Importing Data in One ROW and getting sum particular CELL

    - by Omeshanker
    I am importing data by using .txt file to MS Excel and whole data is imported in ONE ROW. I want to get SUM of those values which corresponds to a particular Month. For Example :- Name Month Total Value Mark Jan 2000 Mark Jan 1500 Mark Feb 2900 Mark Feb 3000 I want to get the TOTAL value in the Month Jan in a particular Cell. Kindly tell me how to proceed. NOTE: Whole data is imported in one ROW only. So the formula should add automatically those values which it finds out on the row. Thanks Omesh

    Read the article

  • Objective-C woes: cellForRowAtIndexPath crashes.

    - by Mr. McPepperNuts
    I want to the user to be able to search for a record in a DB. The fetch and the results returned work perfectly. I am having a hard time setting the UItableview to display the result tho. The application continually crashes at cellForRowAtIndexPath. Please, someone help before I have a heart attack over here. Thank you. @implementation SearchViewController @synthesize mySearchBar; @synthesize textToSearchFor; @synthesize myGlobalSearchObject; @synthesize results; @synthesize tableView; @synthesize tempString; #pragma mark - #pragma mark View lifecycle - (void)viewDidLoad { [super viewDidLoad]; } #pragma mark - #pragma mark Table View - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //handle selection; push view } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ /* if(nullResulSearch == TRUE){ return 1; }else { return[results count]; } */ return[results count]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 1; // Test hack to display multiple rows. } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Search Cell Identifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if(cell == nil){ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier] autorelease]; } NSLog(@"TEMPSTRING %@", tempString); cell.textLabel.text = tempString; return cell; } #pragma mark - #pragma mark Memory management - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; } - (void)viewDidUnload { self.tableView = nil; } - (void)dealloc { [results release]; [mySearchBar release]; [textToSearchFor release]; [myGlobalSearchObject release]; [super dealloc]; } #pragma mark - #pragma mark Search Function & Fetch Controller - (NSManagedObject *)SearchDatabaseForText:(NSString *)passdTextToSearchFor{ NSManagedObject *searchObj; UndergroundBaseballAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext; NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == [c]%@", passdTextToSearchFor]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entry" inManagedObjectContext:managedObjectContext]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; [request setSortDescriptors:sortDescriptors]; [request setEntity: entity]; [request setPredicate: predicate]; NSError *error; results = [managedObjectContext executeFetchRequest:request error:&error]; if([results count] == 0){ NSLog(@"No results found"); searchObj = nil; nullResulSearch == TRUE; }else{ if ([[[results objectAtIndex:0] name] caseInsensitiveCompare:passdTextToSearchFor] == 0) { NSLog(@"results %@", [[results objectAtIndex:0] name]); searchObj = [results objectAtIndex:0]; nullResulSearch == FALSE; }else{ NSLog(@"No results found"); searchObj = nil; nullResulSearch == TRUE; } } [tableView reloadData]; [request release]; [sortDescriptors release]; return searchObj; } - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{ textToSearchFor = mySearchBar.text; NSLog(@"textToSearchFor: %@", textToSearchFor); myGlobalSearchObject = [self SearchDatabaseForText:textToSearchFor]; NSLog(@"myGlobalSearchObject: %@", myGlobalSearchObject); tempString = [myGlobalSearchObject valueForKey:@"name"]; NSLog(@"tempString: %@", tempString); } @end *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UILongPressGestureRecognizer isEqualToString:]: unrecognized selector sent to instance 0x3d46c20'

    Read the article

  • Microsoft guarantees the performance of SQL Server

    - by simonsabin
    I have recently been informed that Microsoft will be guaranteeing the performance of SQL Server. Yes thats right Microsoft will guarantee that you will get better performance out of SQL Server that any other competitor system. However on the flip side there are also saying that end users also have to guarantee the performance of SQL Server if they want to use the next release of SQL Server targeted for 2011 or 2012. It appears that a recent recruit Mark Smith from Newcastle, England will be heading a new team that will be making sure you are running SQL Server on adequate hardware and making sure you are developing your applications according to best practices. The Performance Enforcement Team (SQLPET) will be a global group headed by mark that will oversee two other groups the existing Customer Advisory Team (SQLCAT) and another new team the Design and Operation Group (SQLDOG). Mark informed me that the team was originally thought out during Yukon and was going to be an independent body that went round to customers making sure they didn’t suffer performance problems. However it was felt that they needed to wait a few releases until SQL Server was really there. The original Yukon Independent Performance Enhancement Team (YIPET) has now become the SQL Performance Enforcement Team (SQLPET). When challenged about the change from enhancement to enforcement Mark was unwilling to comment. An anonymous source suggested that "..Microsoft is sick of the bad press SQL Server gets for performance when the performance problems are normally down to people developing applications badly and using inadequate hardware..." Its true that it is very easy to install and run SQL, unlike other RDMS systems and the flip side is that its also easy to get into performance problems due to under specified hardware and bad design. Its not yet confirmed if this enforcement will apply to all SKUs or just the high end ones. I would personally welcome some level of architectural and hardware advice service that clients would be able to turn to, in order to justify getting the appropriate hardware at the start of a project and not 1 year in when its often too late.

    Read the article

  • rsync problems and security concerns

    - by MB.
    Hi I am attempting to use rsync to copy files between two linux servers. both on 10.04.4 I have set up the ssh and a script running under a cron job. this is the message i get back from the cron job. To: mark@ubuntu Subject: Cron ~/rsync.sh Content-Type: text/plain; charset=ANSI_X3.4-1968 X-Cron-Env: X-Cron-Env: X-Cron-Env: X-Cron-Env: Message-Id: <20120708183802.E0D54FC2C0@ubuntu Date: Sun, 8 Jul 2012 14:38:01 -0400 (EDT) rsync: link_stat "/home/mark/#342#200#223rsh=ssh" failed: No such file or directory (2) rsync: opendir "/Library/WebServer/Documents/.cache" failed: Permission denied (13) rsync: recv_generator: mkdir "/Library/Library" failed: Permission denied (13) * Skipping any contents from this failed directory * rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1060) [sender=3.0.7] Q.1 can anyone tell me why I get this message -- rsync: link_stat "/home/mark/#342#200#223rsh=ssh" failed: No such file or directory (2) the script is: #!/bin/bash SOURCEPATH='/Library' DESTPATH='/Library' DESTHOST='192.168.1.15' DESTUSER='mark' LOGFILE='rsync.log' echo $'\n\n' >> $LOGFILE rsync -av –rsh=ssh $SOURCEPATH $DESTUSER@$DESTHOST:$DESTPATH 2>&1 >> $LOGFILE echo “Completed at: `/bin/date`” >> $LOGFILE Q2. I know I have several problems with the permissions all of the files I am copying usually require me to use sudo to manipulate them. My question is then is there a way i can run this job without giving my user root access or using root in the login ?? Thanks for the help .

    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

  • running multi threads in Java

    - by owca
    My task is to simulate activity of couple of persons. Each of them has few activities to perform in some random time: fast (0-5s), medium(5-10s), slow(10-20s) and very slow(20-30s). Each person performs its task independently in the same time. At the beginning of new task I should print it's random time, start the task and then after time passes show next task's time and start it. I've written run() function that counts time, but now it looks like threads are done one after another and not in the same time or maybe they're just printed in this way. public class People{ public static void main(String[] args){ Task tasksA[]={new Task("washing","fast"), new Task("reading","slow"), new Task("shopping","medium")}; Task tasksM[]={new Task("sleeping zzzzzzzzzz","very slow"), new Task("learning","slow"), new Task(" :** ","slow"), new Task("passing an exam","slow") }; Task tasksJ[]={new Task("listening music","medium"), new Task("doing nothing","slow"), new Task("walking","medium") }; BusyPerson friends[]={ new BusyPerson("Alice",tasksA), new BusyPerson("Mark",tasksM), new BusyPerson("John",tasksJ)}; System.out.println("STARTING....................."); for(BusyPerson f: friends) (new Thread(f)).start(); System.out.println("DONE........................."); } } class Task { private String task; private int time; private Task[]tasks; public Task(String t, String s){ task = t; Speed speed = new Speed(); time = speed.getSpeed(s); } public Task(Task[]tab){ Task[]table=new Task[tab.length]; for(int i=0; i < tab.length; i++){ table[i] = tab[i]; } this.tasks = table; } } class Speed { private static String[]hows = {"fast","medium","slow","very slow"}; private static int[]maxs = {5000, 10000, 20000, 30000}; public Speed(){ } public static int getSpeed( String speedString){ String s = speedString; int up_limit=0; int down_limit=0; int time=0; //get limits of time for(int i=0; i<hows.length; i++){ if(s.equals(hows[i])){ up_limit = maxs[i]; if(i>0){ down_limit = maxs[i-1]; } else{ down_limit = 0; } } } //get random time within the limits Random rand = new Random(); time = rand.nextInt(up_limit) + down_limit; return time; } } class BusyPerson implements Runnable { private String name; private Task[] person_tasks; private BusyPerson[]persons; public BusyPerson(String s, Task[]t){ name = s; person_tasks = t; } public BusyPerson(BusyPerson[]tab){ BusyPerson[]table=new BusyPerson[tab.length]; for(int i=0; i < tab.length; i++){ table[i] = tab[i]; } this.persons = table; } public void run() { int time = 0; double t1=0; for(Task t: person_tasks){ t1 = (double)t.time/1000; System.out.println(name+" is... "+t.task+" "+t.speed+ " ("+t1+" sec)"); while (time == t.time) { try { Thread.sleep(10); } catch(InterruptedException exc) { System.out.println("End of thread."); return; } time = time + 100; } } } } And my output : STARTING..................... DONE......................... Mark is... sleeping zzzzzzzzzz very slow (36.715 sec) Mark is... learning slow (10.117 sec) Mark is... :** slow (29.543 sec) Mark is... passing an exam slow (23.429 sec) Alice is... washing fast (1.209 sec) Alice is... reading slow (23.21 sec) Alice is... shopping medium (11.237 sec) John is... listening music medium (8.263 sec) John is... doing nothing slow (13.576 sec) John is... walking medium (11.322 sec) Whilst it should be like this : STARTING..................... DONE......................... John is... listening music medium (7.05 sec) Alice is... washing fast (3.268 sec) Mark is... sleeping zzzzzzzzzz very slow (23.71 sec) Alice is... reading slow (15.516 sec) John is... doing nothing slow (13.692 sec) Alice is... shopping medium (8.371 sec) Mark is... learning slow (13.904 sec) John is... walking medium (5.172 sec) Mark is... :** slow (12.322 sec) Mark is... passing an exam very slow (27.1 sec)

    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

  • UITableview has problem reloading

    - by seelani
    Hi guys, I've kinda finished my application for a school project but have run into a major "bug". It's a account management application. I'm unable to insert a picture here so here's a link: http://i232.photobucket.com/albums/ee112/seelani/Screenshot2010-12-22atPM075512.png Here's the problem when i click on the plus sign, i push a nav controller to load another view to handle the adding and deleting of categories. When i add and return back to the view above, it doesn't update. It only updates after i hit the button on the right which is another view used to change some settings, and return back to the page. I did some research on viewWillAppear and such but I'm still confused to why it doesn't work properly. This problem is also affecting my program when i delete a category, and return back to this view it crashes cos the view has not reloaded successfully. I will get this error when deleting and returning to the view. "* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[NSMutableArray objectAtIndex:]: index 4 beyond bounds [0 .. 3]'". [EDIT] Table View Code: @class LoginViewController; @implementation CategoryTableViewController @synthesize categoryTableViewController; @synthesize categoryArray; @synthesize accountsTableViewController; @synthesize editAccountTable; @synthesize window; CategoryMgmtTableController *categoryMgmtTableController; ChangePasswordView *changePasswordView; - (void) save_Clicked:(id)sender { /* UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Category Management" message:@"Load category management table view" delegate:self cancelButtonTitle: @"OK" otherButtonTitles:nil]; [alert show]; [alert release]; */ KeyCryptAppAppDelegate *appDelegate = (KeyCryptAppAppDelegate *)[[UIApplication sharedApplication] delegate]; categoryMgmtTableController = [[CategoryMgmtTableController alloc]initWithNibName:@"CategoryMgmtTable" bundle:nil]; [appDelegate.categoryNavController pushViewController:categoryMgmtTableController animated:YES]; } - (void) change_Clicked:(id)sender { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Change Password" message:@"Change password View" delegate:self cancelButtonTitle: @"OK" otherButtonTitles:nil]; [alert show]; [alert release]; KeyCryptAppAppDelegate *appDelegate = (KeyCryptAppAppDelegate *)[[UIApplication sharedApplication] delegate]; changePasswordView = [[ChangePasswordView alloc]initWithNibName:@"ChangePasswordView" bundle:nil]; [appDelegate.categoryNavController pushViewController:changePasswordView animated:YES]; /* KeyCryptAppAppDelegate *appDelegate = (KeyCryptAppAppDelegate *)[[UIApplication sharedApplication] delegate]; categoryMgmtTableController = [[CategoryMgmtTableController alloc]initWithNibName:@"CategoryMgmtTable" bundle:nil]; [appDelegate.categoryNavController pushViewController:categoryMgmtTableController animated:YES]; */ } #pragma mark - #pragma mark Initialization /* - (id)initWithStyle:(UITableViewStyle)style { // Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad. if ((self = [super initWithStyle:style])) { } return self; } */ -(void) initializeCategoryArray { sqlite3 *db= [KeyCryptAppAppDelegate getNewDBConnection]; KeyCryptAppAppDelegate *appDelegate = (KeyCryptAppAppDelegate *)[[UIApplication sharedApplication] delegate]; const char *sql = [[NSString stringWithFormat:(@"Select Category from Categories;")]cString]; const char *cmd = [[NSString stringWithFormat:@"pragma key = '%@' ", appDelegate.pragmaKey]cString]; sqlite3_stmt *compiledStatement; sqlite3_exec(db, cmd, NULL, NULL, NULL); if (sqlite3_prepare_v2(db, sql, -1, &compiledStatement, NULL)==SQLITE_OK) { while(sqlite3_step(compiledStatement) == SQLITE_ROW) [categoryArray addObject:[NSString stringWithUTF8String:(char*) sqlite3_column_text(compiledStatement, 0)]]; } else { NSAssert1(0,@"Error preparing statement", sqlite3_errmsg(db)); } sqlite3_finalize(compiledStatement); } #pragma mark - #pragma mark View lifecycle - (void)viewDidLoad { // Uncomment the following line to display an Edit button in the navigation bar for this view controller. // self.navigationItem.rightBarButtonItem = self.editButtonItem; [super viewDidLoad]; } - (void)viewWillAppear:(BOOL)animated { self.title = NSLocalizedString(@"Categories",@"Types of Categories"); categoryArray = [[NSMutableArray alloc]init]; [self initializeCategoryArray]; self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(save_Clicked:)] autorelease]; self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(change_Clicked:)] autorelease]; [super viewWillAppear:animated]; } - (void)viewDidAppear:(BOOL)animated { NSLog (@"view did appear"); [super viewDidAppear:animated]; } - (void)viewWillDisappear:(BOOL)animated { NSLog (@"view will disappear"); [super viewWillDisappear:animated]; } - (void)viewDidDisappear:(BOOL)animated { [categoryTableView reloadData]; NSLog (@"view did disappear"); [super viewDidDisappear:animated]; } /* // Override to allow orientations other than the default portrait orientation. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } */ #pragma mark - #pragma mark Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // Return the number of sections. return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. return [self.categoryArray count]; } // Customize the appearance of table view cells. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } // Configure the cell... NSUInteger row = [indexPath row]; cell.text = [categoryArray objectAtIndex:row]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; return cell; } /* // Override to support conditional editing of the table view. - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { // Return NO if you do not want the specified item to be editable. return YES; } */ /* // Override to support editing the table view. - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { // Delete the row from the data source [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES]; } else if (editingStyle == UITableViewCellEditingStyleInsert) { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } } */ /* // Override to support rearranging the table view. - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { } */ /* // Override to support conditional rearranging of the table view. - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { // Return NO if you do not want the item to be re-orderable. return YES; } */ #pragma mark - #pragma mark Table view delegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSString *selectedCategory = [categoryArray objectAtIndex:[indexPath row]]; NSLog (@"AccountsTableView.xib is called."); if ([categoryArray containsObject: selectedCategory]) { if (self.accountsTableViewController == nil) { AccountsTableViewController *aAccountsView = [[AccountsTableViewController alloc]initWithNibName:@"AccountsTableView"bundle:nil]; self.accountsTableViewController =aAccountsView; [aAccountsView release]; } NSInteger row =[indexPath row]; accountsTableViewController.title = [NSString stringWithFormat:@"%@", [categoryArray objectAtIndex:row]]; // This portion pushes the categoryNavController. KeyCryptAppAppDelegate *delegate = [[UIApplication sharedApplication] delegate]; [self.accountsTableViewController initWithTextSelected:selectedCategory]; KeyCryptAppAppDelegate *appDelegate = (KeyCryptAppAppDelegate *)[[UIApplication sharedApplication] delegate]; appDelegate.pickedCategory = selectedCategory; [delegate.categoryNavController pushViewController:accountsTableViewController animated:YES]; } } #pragma mark - #pragma mark Memory management - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Relinquish ownership any cached data, images, etc that aren't in use. } - (void)viewDidUnload { // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand. // For example: self.myOutlet = nil; } - (void)dealloc { [accountsTableViewController release]; [super dealloc]; } @end And the code that i used to delete rows(this is in a totally different tableview): - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { // Delete the row from the data source NSString *selectedCategory = [categoryArray objectAtIndex:indexPath.row]; [categoryArray removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES]; [deleteCategoryTable reloadData]; //NSString *selectedCategory = [categoryArray objectAtIndex:indexPath.row]; sqlite3 *db= [KeyCryptAppAppDelegate getNewDBConnection]; KeyCryptAppAppDelegate *appDelegate = (KeyCryptAppAppDelegate *)[[UIApplication sharedApplication] delegate]; const char *sql = [[NSString stringWithFormat:@"Delete from Categories where Category = '%@';", selectedCategory]cString]; const char *cmd = [[NSString stringWithFormat:@"pragma key = '%@' ", appDelegate.pragmaKey]cString]; sqlite3_stmt *compiledStatement; sqlite3_exec(db, cmd, NULL, NULL, NULL); if (sqlite3_prepare_v2(db, sql, -1, &compiledStatement, NULL)==SQLITE_OK) { sqlite3_exec(db,sql,NULL,NULL,NULL); } else { NSAssert1(0,@"Error preparing statement", sqlite3_errmsg(db)); } sqlite3_finalize(compiledStatement); } else if (editingStyle == UITableViewCellEditingStyleInsert) { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } }

    Read the article

  • Adding DTrace Probes to PHP Extensions

    - by cj
    The powerful DTrace tracing facility has some PHP-specific probes that can be enabled with --enable-dtrace. DTrace for Linux is being created by Oracle and is currently in tech preview. Currently it doesn't support userspace tracing so, in the meantime, Systemtap can be used to monitor the probes implemented in PHP. This was recently outlined in David Soria Parra's post Probing PHP with Systemtap on Linux. My post shows how DTrace probes can be added to PHP extensions and traced on Linux. I was using Oracle Linux 6.3. Not all Linux kernels are built with Systemtap, since this can impact stability. Check whether your running kernel (or others installed) have Systemtap enabled, and reboot with such a kernel: # grep CONFIG_UTRACE /boot/config-`uname -r` # grep CONFIG_UTRACE /boot/config-* When you install Systemtap itself, the package systemtap-sdt-devel is needed since it provides the sdt.h header file: # yum install systemtap-sdt-devel You can now install and build PHP as shown in David's article. Basically the build is with: $ cd ~/php-src $ ./configure --disable-all --enable-dtrace $ make (For me, running 'make' a second time failed with an error. The workaround is to do 'git checkout Zend/zend_dtrace.d' and then rerun 'make'. See PHP Bug 63704) David's article shows how to trace the probes already implemented in PHP. You can also use Systemtap to trace things like userspace PHP function calls. For example, create test.php: <?php $c = oci_connect('hr', 'welcome', 'localhost/orcl'); $s = oci_parse($c, "select dbms_xmlgen.getxml('select * from dual') xml from dual"); $r = oci_execute($s); $row = oci_fetch_array($s, OCI_NUM); $x = $row[0]->load(); $row[0]->free(); echo $x; ?> The normal output of this file is the XML form of Oracle's DUAL table: $ ./sapi/cli/php ~/test.php <?xml version="1.0"?> <ROWSET> <ROW> <DUMMY>X</DUMMY> </ROW> </ROWSET> To trace the PHP function calls, create the tracing file functrace.stp: probe process("sapi/cli/php").function("zif_*") { printf("Started function %s\n", probefunc()); } probe process("sapi/cli/php").function("zif_*").return { printf("Ended function %s\n", probefunc()); } This makes use of the way PHP userspace functions (not builtins) like oci_connect() map to C functions with a "zif_" prefix. Login as root, and run System tap on the PHP script: # cd ~cjones/php-src # stap -c 'sapi/cli/php ~cjones/test.php' ~cjones/functrace.stp Started function zif_oci_connect Ended function zif_oci_connect Started function zif_oci_parse Ended function zif_oci_parse Started function zif_oci_execute Ended function zif_oci_execute Started function zif_oci_fetch_array Ended function zif_oci_fetch_array Started function zif_oci_lob_load <?xml version="1.0"?> <ROWSET> <ROW> <DUMMY>X</DUMMY> </ROW> </ROWSET> Ended function zif_oci_lob_load Started function zif_oci_free_descriptor Ended function zif_oci_free_descriptor Each call and return is logged. The Systemtap scripting language allows complex scripts to be built. There are many examples on the web. To augment this generic capability and the PHP probes in PHP, other extensions can have probes too. Below are the steps I used to add probes to OCI8: I created a provider file ext/oci8/oci8_dtrace.d, enabling three probes. The first one will accept a parameter that runtime tracing can later display: provider php { probe oci8__connect(char *username); probe oci8__nls_start(); probe oci8__nls_done(); }; I updated ext/oci8/config.m4 with the PHP_INIT_DTRACE macro. The patch is at the end of config.m4. The macro takes the provider prototype file, a name of the header file that 'dtrace' will generate, and a list of sources files with probes. When --enable-dtrace is used during PHP configuration, then the outer $PHP_DTRACE check is true and my new probes will be enabled. I've chosen to define an OCI8 specific macro, HAVE_OCI8_DTRACE, which can be used in the OCI8 source code: diff --git a/ext/oci8/config.m4 b/ext/oci8/config.m4 index 34ae76c..f3e583d 100644 --- a/ext/oci8/config.m4 +++ b/ext/oci8/config.m4 @@ -341,4 +341,17 @@ if test "$PHP_OCI8" != "no"; then PHP_SUBST_OLD(OCI8_ORACLE_VERSION) fi + + if test "$PHP_DTRACE" = "yes"; then + AC_CHECK_HEADERS([sys/sdt.h], [ + PHP_INIT_DTRACE([ext/oci8/oci8_dtrace.d], + [ext/oci8/oci8_dtrace_gen.h],[ext/oci8/oci8.c]) + AC_DEFINE(HAVE_OCI8_DTRACE,1, + [Whether to enable DTrace support for OCI8 ]) + ], [ + AC_MSG_ERROR( + [Cannot find sys/sdt.h which is required for DTrace support]) + ]) + fi + fi In ext/oci8/oci8.c, I added the probes at, for this example, semi-arbitrary places: diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index e2241cf..ffa0168 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -1811,6 +1811,12 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char } } +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_CONNECT_ENABLED()) { + DTRACE_OCI8_CONNECT(username); + } +#endif + /* Initialize global handles if they weren't initialized before */ if (OCI_G(env) == NULL) { php_oci_init_global_handles(TSRMLS_C); @@ -1870,11 +1876,22 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char size_t rsize = 0; sword result; +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_NLS_START_ENABLED()) { + DTRACE_OCI8_NLS_START(); + } +#endif PHP_OCI_CALL_RETURN(result, OCINlsEnvironmentVariableGet, (&charsetid_nls_lang, 0, OCI_NLS_CHARSET_ID, 0, &rsize)); if (result != OCI_SUCCESS) { charsetid_nls_lang = 0; } smart_str_append_unsigned_ex(&hashed_details, charsetid_nls_lang, 0); + +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_NLS_DONE_ENABLED()) { + DTRACE_OCI8_NLS_DONE(); + } +#endif } timestamp = time(NULL); The oci_connect(), oci_pconnect() and oci_new_connect() calls all use php_oci_do_connect_ex() internally. The first probe simply records that the PHP application made a connection call. I already showed a way to do this without needing a probe, but adding a specific probe lets me record the username. The other two probes can be used to time how long the globalization initialization takes. The relationships between the oci8_dtrace.d names like oci8__connect, the probe guards like DTRACE_OCI8_CONNECT_ENABLED() and probe names like DTRACE_OCI8_CONNECT() are obvious after seeing the pattern of all three probes. I included the new header that will be automatically created by the dtrace tool when PHP is built. I did this in ext/oci8/php_oci8_int.h: diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h index b0d6516..c81fc5a 100644 --- a/ext/oci8/php_oci8_int.h +++ b/ext/oci8/php_oci8_int.h @@ -44,6 +44,10 @@ # endif # endif /* osf alpha */ +#ifdef HAVE_OCI8_DTRACE +#include "oci8_dtrace_gen.h" +#endif + #if defined(min) #undef min #endif Now PHP can be rebuilt: $ cd ~/php-src $ rm configure && ./buildconf --force $ ./configure --disable-all --enable-dtrace \ --with-oci8=instantclient,/home/cjones/instantclient $ make If 'make' fails, do the 'git checkout Zend/zend_dtrace.d' trick I mentioned. The new probes can be seen by logging in as root and running: # stap -l 'process.provider("php").mark("oci8*")' -c 'sapi/cli/php -i' process("sapi/cli/php").provider("php").mark("oci8__connect") process("sapi/cli/php").provider("php").mark("oci8__nls_done") process("sapi/cli/php").provider("php").mark("oci8__nls_start") To test them out, create a new trace file, oci.stp: global numconnects; global start; global numcharlookups = 0; global tottime = 0; probe process.provider("php").mark("oci8-connect") { printf("Connected as %s\n", user_string($arg1)); numconnects += 1; } probe process.provider("php").mark("oci8-nls_start") { start = gettimeofday_us(); numcharlookups++; } probe process.provider("php").mark("oci8-nls_done") { tottime += gettimeofday_us() - start; } probe end { printf("Connects: %d, Charset lookups: %ld\n", numconnects, numcharlookups); printf("Total NLS charset initalization time: %ld usecs/connect\n", (numcharlookups 0 ? tottime/numcharlookups : 0)); } This calculates the average time that the NLS character set lookup takes. It also prints out the username of each connection, as an example of using parameters. Login as root and run Systemtap over the PHP script: # cd ~cjones/php-src # stap -c 'sapi/cli/php ~cjones/test.php' ~cjones/oci.stp Connected as cj <?xml version="1.0"?> <ROWSET> <ROW> <DUMMY>X</DUMMY> </ROW> </ROWSET> Connects: 1, Charset lookups: 1 Total NLS charset initalization time: 164 usecs/connect This shows the time penalty of making OCI8 look up the default character set. This time would be zero if a character set had been passed as the fourth argument to oci_connect() in test.php.

    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

  • So…is it a Seek or a Scan?

    - by Paul White
    You’re probably most familiar with the terms ‘Seek’ and ‘Scan’ from the graphical plans produced by SQL Server Management Studio (SSMS).  The image to the left shows the most common ones, with the three types of scan at the top, followed by four types of seek.  You might look to the SSMS tool-tip descriptions to explain the differences between them: Not hugely helpful are they?  Both mention scans and ranges (nothing about seeks) and the Index Seek description implies that it will not scan the index entirely (which isn’t necessarily true). Recall also yesterday’s post where we saw two Clustered Index Seek operations doing very different things.  The first Seek performed 63 single-row seeking operations; and the second performed a ‘Range Scan’ (more on those later in this post).  I hope you agree that those were two very different operations, and perhaps you are wondering why there aren’t different graphical plan icons for Range Scans and Seeks?  I have often wondered about that, and the first person to mention it after yesterday’s post was Erin Stellato (twitter | blog): Before we go on to make sense of all this, let’s look at another example of how SQL Server confusingly mixes the terms ‘Scan’ and ‘Seek’ in different contexts.  The diagram below shows a very simple heap table with two columns, one of which is the non-clustered Primary Key, and the other has a non-unique non-clustered index defined on it.  The right hand side of the diagram shows a simple query, it’s associated query plan, and a couple of extracts from the SSMS tool-tip and Properties windows. Notice the ‘scan direction’ entry in the Properties window snippet.  Is this a seek or a scan?  The different references to Scans and Seeks are even more pronounced in the XML plan output that the graphical plan is based on.  This fragment is what lies behind the single Index Seek icon shown above: You’ll find the same confusing references to Seeks and Scans throughout the product and its documentation. Making Sense of Seeks Let’s forget all about scans for a moment, and think purely about seeks.  Loosely speaking, a seek is the process of navigating an index B-tree to find a particular index record, most often at the leaf level.  A seek starts at the root and navigates down through the levels of the index to find the point of interest: Singleton Lookups The simplest sort of seek predicate performs this traversal to find (at most) a single record.  This is the case when we search for a single value using a unique index and an equality predicate.  It should be readily apparent that this type of search will either find one record, or none at all.  This operation is known as a singleton lookup.  Given the example table from before, the following query is an example of a singleton lookup seek: Sadly, there’s nothing in the graphical plan or XML output to show that this is a singleton lookup – you have to infer it from the fact that this is a single-value equality seek on a unique index.  The other common examples of a singleton lookup are bookmark lookups – both the RID and Key Lookup forms are singleton lookups (an RID lookup finds a single record in a heap from the unique row locator, and a Key Lookup does much the same thing on a clustered table).  If you happen to run your query with STATISTICS IO ON, you will notice that ‘Scan Count’ is always zero for a singleton lookup. Range Scans The other type of seek predicate is a ‘seek plus range scan’, which I will refer to simply as a range scan.  The seek operation makes an initial descent into the index structure to find the first leaf row that qualifies, and then performs a range scan (either backwards or forwards in the index) until it reaches the end of the scan range. The ability of a range scan to proceed in either direction comes about because index pages at the same level are connected by a doubly-linked list – each page has a pointer to the previous page (in logical key order) as well as a pointer to the following page.  The doubly-linked list is represented by the green and red dotted arrows in the index diagram presented earlier.  One subtle (but important) point is that the notion of a ‘forward’ or ‘backward’ scan applies to the logical key order defined when the index was built.  In the present case, the non-clustered primary key index was created as follows: CREATE TABLE dbo.Example ( key_col INTEGER NOT NULL, data INTEGER NOT NULL, CONSTRAINT [PK dbo.Example key_col] PRIMARY KEY NONCLUSTERED (key_col ASC) ) ; Notice that the primary key index specifies an ascending sort order for the single key column.  This means that a forward scan of the index will retrieve keys in ascending order, while a backward scan would retrieve keys in descending key order.  If the index had been created instead on key_col DESC, a forward scan would retrieve keys in descending order, and a backward scan would return keys in ascending order. A range scan seek predicate may have a Start condition, an End condition, or both.  Where one is missing, the scan starts (or ends) at one extreme end of the index, depending on the scan direction.  Some examples might help clarify that: the following diagram shows four queries, each of which performs a single seek against a column holding every integer from 1 to 100 inclusive.  The results from each query are shown in the blue columns, and relevant attributes from the Properties window appear on the right: Query 1 specifies that all key_col values less than 5 should be returned in ascending order.  The query plan achieves this by seeking to the start of the index leaf (there is no explicit starting value) and scanning forward until the End condition (key_col < 5) is no longer satisfied (SQL Server knows it can stop looking as soon as it finds a key_col value that isn’t less than 5 because all later index entries are guaranteed to sort higher). Query 2 asks for key_col values greater than 95, in descending order.  SQL Server returns these results by seeking to the end of the index, and scanning backwards (in descending key order) until it comes across a row that isn’t greater than 95.  Sharp-eyed readers may notice that the end-of-scan condition is shown as a Start range value.  This is a bug in the XML show plan which bubbles up to the Properties window – when a backward scan is performed, the roles of the Start and End values are reversed, but the plan does not reflect that.  Oh well. Query 3 looks for key_col values that are greater than or equal to 10, and less than 15, in ascending order.  This time, SQL Server seeks to the first index record that matches the Start condition (key_col >= 10) and then scans forward through the leaf pages until the End condition (key_col < 15) is no longer met. Query 4 performs much the same sort of operation as Query 3, but requests the output in descending order.  Again, we have to mentally reverse the Start and End conditions because of the bug, but otherwise the process is the same as always: SQL Server finds the highest-sorting record that meets the condition ‘key_col < 25’ and scans backward until ‘key_col >= 20’ is no longer true. One final point to note: seek operations always have the Ordered: True attribute.  This means that the operator always produces rows in a sorted order, either ascending or descending depending on how the index was defined, and whether the scan part of the operation is forward or backward.  You cannot rely on this sort order in your queries of course (you must always specify an ORDER BY clause if order is important) but SQL Server can make use of the sort order internally.  In the four queries above, the query optimizer was able to avoid an explicit Sort operator to honour the ORDER BY clause, for example. Multiple Seek Predicates As we saw yesterday, a single index seek plan operator can contain one or more seek predicates.  These seek predicates can either be all singleton seeks or all range scans – SQL Server does not mix them.  For example, you might expect the following query to contain two seek predicates, a singleton seek to find the single record in the unique index where key_col = 10, and a range scan to find the key_col values between 15 and 20: SELECT key_col FROM dbo.Example WHERE key_col = 10 OR key_col BETWEEN 15 AND 20 ORDER BY key_col ASC ; In fact, SQL Server transforms the singleton seek (key_col = 10) to the equivalent range scan, Start:[key_col >= 10], End:[key_col <= 10].  This allows both range scans to be evaluated by a single seek operator.  To be clear, this query results in two range scans: one from 10 to 10, and one from 15 to 20. Final Thoughts That’s it for today – tomorrow we’ll look at monitoring singleton lookups and range scans, and I’ll show you a seek on a heap table. Yes, a seek.  On a heap.  Not an index! If you would like to run the queries in this post for yourself, there’s a script below.  Thanks for reading! IF OBJECT_ID(N'dbo.Example', N'U') IS NOT NULL BEGIN DROP TABLE dbo.Example; END ; -- Test table is a heap -- Non-clustered primary key on 'key_col' CREATE TABLE dbo.Example ( key_col INTEGER NOT NULL, data INTEGER NOT NULL, CONSTRAINT [PK dbo.Example key_col] PRIMARY KEY NONCLUSTERED (key_col) ) ; -- Non-unique non-clustered index on the 'data' column CREATE NONCLUSTERED INDEX [IX dbo.Example data] ON dbo.Example (data) ; -- Add 100 rows INSERT dbo.Example WITH (TABLOCKX) ( key_col, data ) SELECT key_col = V.number, data = V.number FROM master.dbo.spt_values AS V WHERE V.[type] = N'P' AND V.number BETWEEN 1 AND 100 ; -- ================ -- Singleton lookup -- ================ ; -- Single value equality seek in a unique index -- Scan count = 0 when STATISTIS IO is ON -- Check the XML SHOWPLAN SELECT E.key_col FROM dbo.Example AS E WHERE E.key_col = 32 ; -- =========== -- Range Scans -- =========== ; -- Query 1 SELECT E.key_col FROM dbo.Example AS E WHERE E.key_col <= 5 ORDER BY E.key_col ASC ; -- Query 2 SELECT E.key_col FROM dbo.Example AS E WHERE E.key_col > 95 ORDER BY E.key_col DESC ; -- Query 3 SELECT E.key_col FROM dbo.Example AS E WHERE E.key_col >= 10 AND E.key_col < 15 ORDER BY E.key_col ASC ; -- Query 4 SELECT E.key_col FROM dbo.Example AS E WHERE E.key_col >= 20 AND E.key_col < 25 ORDER BY E.key_col DESC ; -- Final query (singleton + range = 2 range scans) SELECT E.key_col FROM dbo.Example AS E WHERE E.key_col = 10 OR E.key_col BETWEEN 15 AND 20 ORDER BY E.key_col ASC ; -- === TIDY UP === DROP TABLE dbo.Example; © 2011 Paul White email: [email protected] twitter: @SQL_Kiwi

    Read the article

< Previous Page | 21 22 23 24 25 26 27 28 29 30 31 32  | Next Page >