-
Notifications
You must be signed in to change notification settings - Fork 435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Significant performance degradation in SQLServerDatabaseMetadata in 6.4.0 #665
Comments
I think one improvement here, could be made that the routine does an early return if the Any suggestions? |
Hi @woehrl01, thanks for submitting the issue. I've confirmed there is significant performance degradation when executing getImportedKeys(). I looked through the old pull request and it seems to address a sp_fkeys deficiency regarding limited return values. However, despite the thread mentioning that the stored procedure won't be fixed, this msdn document claims otherwise. I have confirmed that sp_fkeys can successfully return values ranging from 0-3. In lieu of these changes, I propose we attempt to revert the PR as it is no longer necessary (but I see some of the values are flipped compared to sys.foreign_keys so it might take some adjusting). Does this solution sound reasonable? |
Hi @rene-ye, thanks for your feedback! After thinking a while about this, I think that a more optimal solution would be, by using only the This should result in a much better preforming statement, which is a lot more readable, too. If you're unsure what I mean, I could provide the statement inlined into this issue or a full a PR in the next days. How does this sound to you? |
Sorry for closing and reopen. I accidentally hit the wrong button 🙈 |
Hi @woehrl01, please feel free to add information/submit a PR if you have time. The team is happy to review and consider all possibilities when deciding on a solution to satisfy everyone. |
Hi @rene-ye , I'll provide a PR, due to some busy times, this will take a few days. |
Hi @woehrl01, I know you're in the process of a PR, but I'd like to share some of my findings on this issue with you and get some of your opinions on possible changes. I created a temporary PR on my fork to make this easier, you can click the above or this link.
Only using sys tables All in all, I think this issue is important and a fix is necessary, so thank you for creating this thread. Performance degradation is to be expected as the previous PR was meant to align the driver with JDBC Specs. I'm just not sure at this point how much we can do to minimize the impact. If you could take a look at some of the changes and get back to me on your thoughts, that'd be great. |
Hi @rene-ye ! Thanks for your detailed response, I already created the sql which should output the desired values, I haven't gotten the time yet to make it a fully PR. Just in case we are aligned: create table #fkeys_results ( --or variable to don't need a drop: declare @fkeys_result table
PKTABLE_QUALIFIER sysname,
PKTABLE_OWNER sysname,
PKTABLE_NAME sysname,
PKCOLUMN_NAME sysname,
FKTABLE_QUALIFIER sysname,
FKTABLE_OWNER sysname,
FKTABLE_NAME sysname,
FKCOLUMN_NAME sysname,
KEY_SEQ smallint,
UPDATE_RULE smallint,
DELETE_RULE smallint,
FK_NAME sysname,
PK_NAME sysname,
DEFERRABILITY smallint
);
insert into #fkeys_results
exec sp_fkeys ?, ?, ?, ?, ?, ?;
select fkr.PKTABLE_QUALIFIER, fkr.PKTABLE_OWNER, fkr.PKTABLE_NAME, fkr.PKCOLUMN_NAME,
fkr.FKTABLE_QUALIFIER, fkr.FKTABLE_OWNER, fkr.FKTABLE_NAME, fkr.FKCOLUMN_NAME,
fkr.KEY_SEQ, fkr.FK_NAME, fkr.PK_NAME, fkr.DEFERRABILITY,
case fkr.UPDATE_RULE
when 0 then 3
when 1 then 0
when 2 then 2
when 3 then 4
else null
end as UPDATE_RULE,
case fkr.DELETE_RULE
when 0 then 3
when 1 then 0
when 2 then 2
when 3 then 4
else null
end as DELETE_RULE
from #fkeys_result fkr
If we pass in the parameter array to that statement instead of the single call to |
Hi @woehrl01, I looked through the SQL code and in general it's what I'm using. It's worth mentioning that there's currently a deficiency with |
Yes, it looks similar to your SQL code, just wanted to share my thoughts. Interesting that |
I'm going to try that right now and see if it resolves some issues I had with drop. It seems to work just fine on SSMS and I'm going to use it over creating a temp table if I can. Edit: It seems to work just fine, going forward with the implementation. It's probably going to be awhile before I can create a PR for this issue as it has brought some problems into light, and I'd like to address all of them before proceeding. |
Hi @woehrl01, I've put together a fix and was wondering if you'd be interested in testing its performance. It's worth noting that I'm using a PreparedStatement instead of a regular Statement to execute the SQL. A regular Statement has security problems, but is noticeably faster. I'll attach the jars in this post. |
Hi @rene-ye , wow that was fast! I'll give those a try and will reach back to you. Thanks! Just out of interest, which kind of security concerns do you have with a regular statement? |
There have been cases where a user is able to perform an SQL injection through getImportedKeys(String,String,String)/getExportedKeys/getCrossReference. |
Thanks, that's reasonable. I wasn't aware that in jdbc the only way to pass parameters is by using a prepared statement. (I'm mostly active in the .Net world, where can do differently) e.g. By using sp_executesql in a single roundtrip. I was looking through your pr and it looks pretty complete, I think the best is that we simply use your code. As due to limited time on my side I'm still struggling executing the unit tests) What do you think? |
I'll look into some other options for the prepared statement, but other than that I'll create the PR in the near future. Thanks for all your time and help. |
I see that you're working on the getResultSetForForeignKeyInformation code--I just reported another related bug at #681 . |
#677 has now been merged. Closing the issue. |
Driver version or jar name
I'm using the 6.4.0.jre8 in comparison to the 6.2.2.jre8.
SQL Server version
Microsoft SQL Server 2012 - 11.0.5343.0 (X64)
Client operating system
Microsoft Windows 10 Pro (10.0.16299)jav
Java/JVM version
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
Problem description
After upgrading the driver from 6.2.2.jre8 to 6.4.0.jre8 I encounter a serious performance degradation in querying the metadata of the database.
The following screenshot is from the opensource tool symmetricds with the 6.2.2.jre8 driver, where you see a total execution time of 44 seconds for a method.
In the second screenshot you see the same code just with using the 6.4.0.jre8 driver, you can see that the total execution time is now 2 times slower (128 seconds).
If you tear down the callstack you'll see that the difference is in the sql server jdbc part where in the later screenshot the
getImportedKeys
is a lot slower than in the 6.2.2.jre8 version.Expected behavior and actual behavior
I'd expect that the two drivers should behave equally. At least I don't expect a performance penalty of 200%.
Repro code
https://github.com/JumpMind/symmetric-ds you have to replace the driver with mssql-jdbc.
The text was updated successfully, but these errors were encountered: