1

The following procedure insert_attach takes less than one second on dbms but it takes about 7 seconds when run it through asp.net method !! :

 public static int InsertAttach(int taskCode, int transYear, int transSerial, int empNum)
    {

        using (IfxConnection con = new IfxConnection(ConfigurationSettings.AppSettings["cmr"].ToString()))
        {
            int res = 0;
            StringBuilder cmdTxt = new StringBuilder();
            cmdTxt.Append("insert_attach");

            using (var myIfxCmd = new IfxCommand(cmdTxt.ToString(), con))
            {

                myIfxCmd.CommandType = CommandType.StoredProcedure;
                myIfxCmd.Parameters.Add("al_task_code", IfxType.Integer);
                myIfxCmd.Parameters.Add("al_trans_year", IfxType.Integer);
                myIfxCmd.Parameters.Add("al_trans_serial", IfxType.Integer);
                myIfxCmd.Parameters.Add("al_emp_num", IfxType.Integer);

                myIfxCmd.Parameters[0].Value = ((object)taskCode) ?? DBNull.Value;
                myIfxCmd.Parameters[1].Value = ((object)transYear) ?? DBNull.Value;
                myIfxCmd.Parameters[2].Value = ((object)transSerial) ?? DBNull.Value;
                myIfxCmd.Parameters[3].Value = ((object)empNum) ?? DBNull.Value;
                if (con.State == ConnectionState.Closed)
                {
                    con.Open();//takes no time
                }

                object obj = myIfxCmd.ExecuteScalar();//takes longer time !!
                if (obj != null && !string.IsNullOrEmpty(obj.ToString()))
                {
                    res = int.Parse(obj.ToString());
                }
            }
            con.Close();
            con.Dispose();
            return res;
        }

    }

My Procedure :

CREATE PROCEDURE insert_attach(
    al_task_code        INT,
    al_trans_year       INT,
    al_trans_serial     INT,
    al_emp_num          INT
)

returning INT;
define ll_state_serial , ll_prev_trans integer;
define ls_values_key VARCHAR(60);
define lbt_file_content , lbt_file_signed , lbt_file_null , lbt_file,  lbt_file_origin REFERENCES byte;

let lbt_file_null = NULL;


SELECT a.new_state_serial,
       values_key,
       a.prev_trans INTO     ll_state_serial,
       ls_values_key,
       ll_prev_trans
FROM   crm_trans             a
WHERE  a.task_code = al_task_code
       AND a.trans_year = al_trans_year
       AND a.trans_serial = al_trans_serial;


DELETE 
FROM   crm_tempdetails
WHERE  temp_serial IN (SELECT temp_serial
                       FROM   crm_tempsigned
                       WHERE  task_code = al_task_code
                              AND values_key = ls_values_key
                              AND emp_num = al_emp_num);

DELETE 
FROM   crm_tempsigned
WHERE  task_code = al_task_code
       AND values_key = ls_values_key
       AND emp_num = al_emp_num
       AND serial != 0;

-- insert into temp 
INSERT INTO crm_tempsigned
  (
    task_code,
    values_key,
    trans_year,
    trans_serial,
    serial,
    file_type,
    file_content,
    file_signed,
    emp_num,
    doc,
    selected
  )
SELECT a.task_code,
       ls_values_key,
       a.trans_year,
       a.trans_serial,
       a.serial,
       a.file_type,
       a.attach_content,
       lbt_file_null,
       al_emp_num,
       a.doc,
       1
FROM   crm_taskattachements     a,
       crm_trans                b
WHERE  a.task_code = b.task_code
       AND a.trans_serial = b.trans_serial
       AND a.trans_year = b.trans_year
       AND a.task_code = al_task_code
       AND b.trans_year = al_trans_year
       AND b.prev_trans = ll_prev_trans
       AND b.values_key = ls_values_key
       AND (
               a.serial IN (SELECT x.file_serial
                            FROM   crm_attachdetails x
                            WHERE  x.task_code = a.task_code
                                   AND x.trans_serial = a.trans_serial
                                   AND x.trans_year = a.trans_year
                                   AND x.emp_num = al_emp_num)
               OR 0 = (
                      SELECT COUNT(*)
                      FROM   crm_attachdetails x
                      WHERE  x.task_code = a.task_code
                             AND x.trans_serial = a.trans_serial
                             AND x.trans_year = a.trans_year
                  )
           );
RETURN 1;
END PROCEDURE
Sergio
  • 6,900
  • 5
  • 31
  • 55
Anyname Donotcare
  • 11,113
  • 66
  • 219
  • 392
  • Have you invoked asp.net method from the same computer where you tested on dbms? Here my point is just confirm that there is no network overhead. – Jenish Rabadiya Feb 25 '15 at 11:27
  • @JenishRabadiya:yes, from the same computer and over the same network , open the connection takes no time ,but execute the procedure takes longer time through my method !! – Anyname Donotcare Feb 25 '15 at 11:47
  • That exact scenario is often due *Parameter Sniffing* although I'm not familiar with how Informix deals with such things – Alex K. Feb 25 '15 at 11:56
  • @just_name what version of visual studio are you using? – Rex Feb 27 '15 at 19:26
  • "select a.new_state_serial , values_key , a.prev_trans into ll_state_serial , ls_values_key , ll_prev_trans from crm_trans a where a.task_code = al_task_code and a.trans_year = al_trans_year and a.trans_serial = al_trans_serial ;" why this part is included in stored proceduere? As from you code it seems that you do not need any dataset as you have used ExecuteScalar(). – GMD Feb 28 '15 at 07:52
  • How you are measuring time taken? Are you looking through SQL profiler to see how query is generated and and how much time it takes to run same generated query? – Arindam Nayak Feb 28 '15 at 15:09
  • @ArindamNayak : i use server studio to run my proc and it shows how much time it takes – Anyname Donotcare Mar 01 '15 at 09:43
  • 2
    Are you only running that method in asp.net, or is it part of a larger process? If part of a larger process, is there any chance that some other code is temporarily blocking your insert here? Try running "sp_who2 active" in SSMS during the 7 seconds to see if there is anything else that might be blocking your SPID. – jlee-tessik Mar 05 '15 at 04:20
  • First of all, try to upgrade your driver. If it won't help... How much data is retrieved by this procedure? – Ginden Mar 05 '15 at 20:04
  • This is a daft question... it takes 10 mins to cook a stew, but when I ask someone else to buy the ingredients and cook it, it takes 70 mins... sooo many variables, and hardly any are specified in the question. – Paul Zahra Mar 06 '15 at 11:16

6 Answers6

2

This question can only be answered by you at the moment. You need to profile your application and the report will tell you exactly which part takes how long.

Going from there you can start investigating why something takes long and then you can ask a concrete question which we might be able to help you with. Right now there is a big block of code and all you say is it takes 7 seconds. All we can do is playing a guessing game, no?

To be honest, I don't even know how you got the 7 seconds? Did you put a timer into your code, if yes where, did you watch the clock on your wall, etc.?

Please have a look at a Profiler. A popular solution is DotTrace: https://www.jetbrains.com/profiler/

See: Profiling C# / .NET applications

Community
  • 1
  • 1
dustinmoris
  • 3,195
  • 3
  • 25
  • 33
1

I would suggest installing Glimpse here or alternatively from Nuget. While some of the answers you have already received explain some of what could be going on, not to the degree of a 7 second difference though. Glimpse is easy to configure and should point you in the correct direction of the issue quickly.

BMac
  • 2,183
  • 3
  • 22
  • 30
0

There is a always some overhead when using a wrapped solution. In this example, you're expecting C# code to run as well as a native SQL query. Given that there are many extra steps that the C# has to take before running the query on the database, it makes sense that it takes longer.

The C# code is also doing a lot of type checking, casting etc. before even attempting to execute, so perhaps you might look at your code and see if you can make any optimisations in the C#? Or perhaps you need to look into optimised methods of executing large queries using C#.

Nathan White
  • 1,082
  • 7
  • 21
0

I think a good start will be add tracing in major steps (etc. Connection opening) and then run SQL Profiler in parallel with one Trace. You can use different strategy to optimize the stuff once you know the problem area. Please share your stats, then we can discuss optimization.

Gaurav Sharma
  • 586
  • 3
  • 10
0

7 seconds is lot of time for an insert operation. The Informix data provider which is used in your code could be performing set of operations which is wrapped inside the IFXCommand.Execute method. You could use ILSpy or Reflector tool to disassemble the data provider and validate what is the extra code that is actually taking time.

I agree to Nathan White for C# performing lot of type checking and casting which can hit the performance of the function.

Anilkumar
  • 115
  • 1
  • 6
0

You try with ARITHABORT option. SET ARITHABORT On after you logdedon the sql from application.

SqlCommand CmdArithabort = new SqlCommand("SET ARITHABORT ON", ConnApp);
CmdArithabort.ExecuteNonQuery();

add this line before your procedure call.This might help you

refer this link:https://msdn.microsoft.com/en-us/library/ms190306.aspx

See the Remarks part.The first line is

You should always set ARITHABORT to ON in your logon sessions. Setting ARITHABORT to OFF can negatively impact query optimization leading to performance issues.