Oracle query is slow (or fails) from .NET app but is fast from SQL Developer

岁酱吖の 提交于 2019-12-03 11:53:47

It had nothing to do with the ODP.NET provider. The problem was that the library we use to create connections for us (which, of course, is not used by Oracle SQL Developer, and which I did not use when I tried the Microsoft provider) was always executing the following statements before doing anything:

ALTER SESSION SET NLS_COMP = LINGUISTIC
ALTER SESSION SET NLS_SORT = BINARY_CI

These make Oracle case-insensitive. But, they also render all conventional indexes useless. Because we were querying from a View, it had ordering built in. And because we don't own the database, we can't make the indexes linguistic to fix the performance problem.

Providing a way to not execute those statements in this (rare) scenario fixed the problem.

Immediate thoughts are

  1. CLOB, BLOB or LONG/LONG RAW which requires a lot of bandwidth for just a few rows.
  2. Invalid data (eg there are ways to get an invalid date into a date field, which may confuse some clients)
  3. "the_table" isn't actually a table but a view or something with a complex derivation or has a VPD/RLS/FGAC security policy on it.
  4. Exotic datatype (Spatial or User Defined).

Suggestions

  1. Explicitly list the columns (eg SELECT a,b,c FROM the_table WHERE ROWNUM < 5). Add columns one by one until it stops working. That assumes there is at least one 'simple' column in the table.
  2. Check the session in v$session to see what the wait EVENT is. Either the DB server is burning CPU for this SQL, or it is waiting for something (possibly the client).
  3. Check the SQL in v$sql. Is there one or more child cursors. is there one or more PLAN_HASH_VALUEs. Different child cursors can use different plans. Without a WHERE clause other than ROWNUM, this is pretty unlikely.

A view adds a different magnitude of complexity. A "SELECT column FROM table WHERE rownum < 5" has probably just a single explain plan, picking data from a single local object.

For a view you should start by getting the view text SELECT TEXT FROM ALL_VIEWS WHERE VIEW_NAME = ...

There's a lot that can be different between an ODP.NET and an SQL Developer session. I'd think about NLS parameters (such as date formats) and character set settings.

If you can locate the SQL in v$sql, you can do a DBMS_XPLAN.DISPLAY_CURSOR(sql_id) to look at the different plans and see if you can identify the problem.

On a project I was working on at my former employer, we were using odp.net to talk to a large retailing system database and we'd get connection lost errors.

It took a lot of effort to prove, but it ended up being a corrupt index inside the Oracle database that was only being hit by our query. The DBA's eventually traced it to a coredump of the process that run on the Sun box when our query was being executed. We didn't use any sort of query hinting etc, but when we ran the same query in Toad, it didn't hit this particular index. strange??<<

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!