In the Sales Line table we have a primary key ("Document Type","Document No.","Line No.") which is unique and clustered. It seems to me that the "Document Type" field in this key has a bad data selectivity. I want to enhance the performance using another secondary key like "Document No.","Document Type","Line No.". Will it be better to use this key instead of primary key?
Thanks in advance.
Nil desperandum
0
Comments
Second - even if you do this you'll have to go through all code in tabels, codeunits, reports. etc, find all record variables based on table 37, find all gets(...) which relate to them, and change field order in get call parameters.
If you even do this, using for example Developer Toolkit, which helps you in finding all variable records based on table 37, you will not be able perform any upgrade, apply any updates, because you'll have to do this job on every new object added to database.
I wouldn't do that.
Regards,
Slawek
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
SalesLine.SETCURRENTKEY("Document No.","Document Type","Line no.");
SalesLine.setfilter("Document Type",DocType);
SalesLine.setfilter("Document No.", DocNo);
SalesLine.Setrange("Line no.", lineNo);
SalesLine.find('-');
I'm not sure if it will be fasetr than simple SalesLine.get(..)
In my opinion your new key would be usable only if you want to browse through sales lines sorting them by document no., regardless of document type. I can't see what it could be good for, but of course you may have such a need.
Regards,
Slawek
Dynamics NAV, MS SQL Server, Wherescape RED;
PRINCE2 Practitioner - License GR657010572SG
GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
2] For each version is different answer... :-)
MVP - Dynamics NAV
My BLOG
NAVERTICA a.s.
Navision appends the primary key fields after any extended keys, so I would Not use the primary key fields in this Instance, as the new key will bring the fastest result.
So if your New key was just "Document No." you would still be able to use the primary fields in your selection construction.
SalesLine.SETCURRENTKEY("Document No.");
SalesLine.SETRANGE("Document No.", DocNo);
SalesLine.Setrange("Document type", DocType);
IF SalesLine.find('-')THEN;
Navision will use the Fields from the Extended Key first, then the primary key fields, in Order.
So the First Line of the selection will be found.
So if your New key was just "Type","No." you would still be able to use the primary fields in your selection construction.
SalesLine.SETCURRENTKEY(Type,"No.");
SalesLine.Setrange(type,SalesLine.Type::Item);
SalesLine.Setrange("No.",Item."No.");
SalesLine.SETRANGE("Document type",SalesLine."Document Type"::Order)
IF SalesLine.find('-')THEN;
Navision will use the Fields from the Extended Key first, then the primary key fields, in Order.
So the First "Order" Sales Line with the selected "Item" will be found.
But if you have the 3 primary values, by far the quickest is:
IF SalesLine.GET(DocType,DocNo,LineNo)THEN;
Mobile: +44(0)7854 842801
Email: david.cox@adeptris.com
Twitter: https://twitter.com/Adeptris
Website: http://www.adeptris.com
We use Navision SQL 3.70A. What is the answer in our case? :-)
But it looks like a Query Optimizer always picks the clustered primary key in this case: It doesn't pick the suggested secondary key ("Document No.") - so the primary key is supposed to be the fastest by the Query Optimizer. I saw this in a SQL Profiler trace.
This secondary key is picked by the Query Optimizer only in this case:
So where is the truth?
Example:
Navision uses a key (“Document Type”, “Customer No”). An index (“Document Type”, “Customer No”) will have a lower selectivity than (“Customer No.”, “Document Type”). Create a new key ((“Customer No.”, “Document Type”) and turn off the maintenance of the first index in SQL. In 4.0 you can use the SQLIndex property.
P.S. We use Navision 3.70A.
It is important to understand the difference between Navision KEYS and SQL Server INDEXES. You NEED Navision keys to ake the application order stuff by certain fields. There is only one way that Navision will allow you to order and that is to create a key for your required sort order. If that key just happens to have a non-selective field, that simply means that SQL Server will never use the index for data retrieval, and you should turn the SQLIndex property off. If SQL Server won't use the index, you should not have to update it.
It works a little differently with primary, clusetered indexes. How exacly I don't know, but suffice to say that you need the uniqueness of the primary key constraint to identify a record. SQL Server actually uses something else to make a record unique, but we're dealing with Navision here
RIS Plus, LLC
Again, SETCURRENTKEY translates into ORDER BY. If SQL Server takes the sort order into account when selecting the index then yes it does have an effect, but it is not a one-to-one relationship.
The way it was explained to me is that the filters that you set have a bigger impact on which index is used than the key you select (i.e. the sort order). If you set a key with 12 fields, and you only set filters on two of them, SQL Server will select the index that has those two fields (IF it exists of course), and it will sort the resulting record set on the fly.
There's a way to see how SQL Server decides which key it uses in the Query Analyzer, but I can't remember how that works.
RIS Plus, LLC
This shows you the exact SQL statements that Navision uses.
You can copy this statement and experiment with it using the enterprise manager to see what it does.
We used this to experiment with the FINDFIRST and FINDLAST functions.
RIS Plus, LLC
I've turned on everything everywhere :-). I see some Client Monitor records with a column "SQL Index Conflict" filled in. What does it mean?
http://www.mibuso.com/forum/viewtopic.p ... x+conflict
Does reading this anwer the question or do we need to further investigate?
RIS Plus, LLC
The number of records can also effect the query plan. With a small number of records, SQL will tend to use the clustered index even if there is an index that matches your filters.
You can see this by comparing the behavior of a ledger table in a small database (say CRONUS) to a large production DB with a large number of records.
Unfortunately it doesn't. That thread is addressed to another headache issue - we can't solve these deadlocks not automatically resolved which lead to a client hang.
Any hints about "SQL Index Conflict" will be appreciated.
If you do this all kind of links are provided about Index Conflicts.
Maybe also MSDN has some information about this.