Slow procedure execution
Hello, I have this stored procedure that runs okay with some calls and very slow with the following call.
SET TIMING ON
VAR V1 REFCURSOR
EXECUTE SP_SEARCH_CUSTOMERS_BASIC(NULL, 'miller', NULL, NULL, NULL, NULL, '06413', :V1, 0);
print V1
-- STORED PROCEDURE
CREATE OR REPLACE PROCEDURE SP_SEARCH_CUSTOMERS_BASIC(
customerAcctNum IN NVARCHAR2,
lastName IN NVARCHAR2,
firstName IN NVARCHAR2,
homePhone IN VARCHAR2,
workPhone IN VARCHAR2,
associateNumber IN NVARCHAR2,
postalCode IN NVARCHAR2,
cur_OUT IN OUT SYS_REFCURSOR,
filterAltAccountOnly IN INTEGER := 0 -- nonzero = only return customers having preferred alt ID
IS
customerId NUMBER;
lastNameValue NVARCHAR2(45);
firstNameValue NVARCHAR2(45);
homePhoneValue VARCHAR2(30);
workPhoneValue VARCHAR2(30);
postalCodeValue NVARCHAR2(15);
limitRows NUMBER := 100; -- limit result set size for performance
-- TODO: take this from a config
preferredAltIDFormat VARCHAR2(30) := '7_____________'; -- 14 digits, first digit always 7
BEGIN
-- Initialize variables!
lastNameValue := NULL;
firstNameValue := NULL;
homePhoneValue := NULL;
workPhoneValue := NULL;
postalCodeValue := NULL;
IF lastName IS NOT NULL THEN
lastNameValue := UPPER(lastName) || '%';
END IF;
IF firstName IS NOT NULL THEN
firstNameValue := UPPER(firstName) || '%';
END IF;
IF homePhone IS NOT NULL THEN
homePhoneValue := homePhone;
END IF;
IF workPhone IS NOT NULL THEN
workPhoneValue := workPhone;
END IF;
IF postalCode IS NOT NULL THEN
postalCodeValue := postalCode || '%';
END IF;
-- Writing a single query that is efficient for all cases is non-trivial.
-- Break the cases out into a few subcases and let them be analyzed separately.
IF customerAcctNum IS NOT NULL THEN
-- Getting the ID separately, instead of through an additional inner join on the select, is faster
customerId := FN_GET_CUSTOMER_ID(customerAcctNum);--VALID CUSTOMER NUMBER IS EXPECTED
OPEN cur_OUT FOR
SELECT DISTINCT /*+ INDEX(CUSTOMER XPKCUSTOMER) +*/
CUSTOMER.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
NULL -- customerAcctNum
) AS CUST_ID,
CUSTOMER.LAST_NAME AS CUST_LST_NM,
CUSTOMER.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM CUSTOMER
LEFT OUTER JOIN ASSOCIATE -- Could have a customer without an associate
ON ASSOCIATE.ASSOCIATE_ID = CUSTOMER.SALESPERSON_ID
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN CUSTOMER_ADDR
ON CUSTOMER_ADDR.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
WHERE CUSTOMER.CUSTOMER_ID = customerId
AND (ASSOCIATE.ASSOCIATE_NUMBER = associateNumber OR associateNumber IS NULL) --RESTRICT ONLY IF AN ASSOCIATE NUMBER IS SUPPLIED
AND (CUSTOMER.LAST_NAME LIKE lastNameValue OR lastNameValue IS NULL) -- RESTRICT ONLY IF A LAST NAME IS SUPPLIED
AND (CUSTOMER.FIRST_NAME LIKE firstNameValue OR firstNameValue IS NULL) --RESTRICT ONLY IF A FIRST NAME IS SUPPLIED
AND (CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue OR postalCodeValue IS NULL) --RESTRICT ONLY IF A POSTAL CODE IS SUPPLIED
AND (CUSTOMER_HOME_PHONE.PHONE_NUM = homePhoneValue OR homePhoneValue IS NULL) --RESTRICT ONLY IF A HOME PHONE NUMBER IS SUPPLIED
AND (CUSTOMER_WORK_PHONE.PHONE_NUM = workPhoneValue OR workPhoneValue IS NULL) --RESTRICT ONLY IF A WORK PHONE NUMBER IS SUPPLIED
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND Is_Deleted = 0
AND ROWNUM <= limitRows
ELSE
-- customerAcctNum IS NULL
IF associateNumber IS NOT NULL THEN
OPEN cur_OUT FOR
SELECT DISTINCT /*+ INDEX(CUSTOMER XIF22CUSTOMER) */ /* FIRST_ROWS(100) +*/
CUSTOMER.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
NULL -- CUSTOMER.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER.LAST_NAME AS CUST_LST_NM,
CUSTOMER.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM ASSOCIATE
INNER JOIN CUSTOMER
ON CUSTOMER.SALESPERSON_ID = ASSOCIATE.ASSOCIATE_ID
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN CUSTOMER_ADDR
ON CUSTOMER_ADDR.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
WHERE ASSOCIATE.ASSOCIATE_NUMBER = associateNumber
AND (CUSTOMER.LAST_NAME LIKE lastNameValue OR lastNameValue IS NULL) -- RESTRICT ONLY IF A LAST NAME IS SUPPLIED
AND (CUSTOMER.FIRST_NAME LIKE firstNameValue OR firstNameValue IS NULL) --RESTRICT ONLY IF A FIRST NAME IS SUPPLIED
AND (CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue OR postalCodeValue IS NULL) --RESTRICT ONLY IF A POSTAL CODE IS SUPPLIED
AND (CUSTOMER_HOME_PHONE.PHONE_NUM = homePhoneValue OR homePhoneValue IS NULL) --RESTRICT ONLY IF A HOME PHONE NUMBER IS SUPPLIED
AND (CUSTOMER_WORK_PHONE.PHONE_NUM = workPhoneValue OR workPhoneValue IS NULL) --RESTRICT ONLY IF A WORK PHONE NUMBER IS SUPPLIED
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND Is_Deleted = 0
AND ROWNUM <= limitRows
ELSE
-- customerAcctNum IS NULL AND associateNumber IS NULL
IF homePhoneValue IS NOT NULL OR workPhoneValue IS NOT NULL THEN
OPEN cur_OUT FOR
SELECT DISTINCT /*+ INDEX(PHONE XIE2PHONE) */ /* FIRST_ROWS(100) +*/
CUSTOMER1.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer1.Customer_ID
AND
Alt_Acct_Num <> Customer1.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
NULL -- CUSTOMER1.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER1.LAST_NAME AS CUST_LST_NM,
CUSTOMER1.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM PHONE ALL_PHONE
INNER JOIN (
SELECT /*+ INDEX(CUSTOMER XPKCUSTOMER) +*/
FROM
CUSTOMER
WHERE
CUSTOMER_ID IN (
SELECT CUSTOMER_ID /*+ INDEX(PHONE XIE2PHONE) +*/
FROM PHONE
WHERE (PHONE.PHONE_NUM IN (homePhoneValue, workPhoneValue)) -- indexed query
AND Is_Deleted = 0
) CUSTOMER1
ON CUSTOMER1.CUSTOMER_ID = ALL_PHONE.CUSTOMER_ID
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN CUSTOMER_ADDR
ON CUSTOMER_ADDR.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
WHERE (ALL_PHONE.PHONE_NUM = homePhoneValue OR ALL_PHONE.PHONE_NUM = workPhoneValue) -- indexed query
AND (CUSTOMER1.LAST_NAME LIKE lastNameValue OR lastNameValue IS NULL) -- RESTRICT ONLY IF A LAST NAME IS SUPPLIED
AND (CUSTOMER1.FIRST_NAME LIKE firstNameValue OR firstNameValue IS NULL) --RESTRICT ONLY IF A FIRST NAME IS SUPPLIED
AND (CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue OR postalCodeValue IS NULL) --RESTRICT ONLY IF A POSTAL CODE IS SUPPLIED
AND (CUSTOMER_HOME_PHONE.PHONE_NUM = homePhoneValue OR homePhoneValue IS NULL) --RESTRICT ONLY IF A HOME PHONE NUMBER IS SUPPLIED
AND (CUSTOMER_WORK_PHONE.PHONE_NUM = workPhoneValue OR workPhoneValue IS NULL) --RESTRICT ONLY IF A WORK PHONE NUMBER IS SUPPLIED
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer1.Customer_ID
AND
Alt_Acct_Num <> Customer1.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND ROWNUM <= limitRows
ELSE
-- customerAcctNum IS NULL AND associateNumber IS NULL AND phone numbers are null
IF postalCodeValue IS NOT NULL THEN
OPEN cur_OUT FOR
SELECT DISTINCT /*+ INDEX(CUSTOMER_ADDR XIE1CUSTOMER_ADDR) */ /* FIRST_ROWS(100) +*/
CUSTOMER1.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer1.Customer_ID
AND
Alt_Acct_Num <> Customer1.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
NULL -- CUSTOMER1.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER1.LAST_NAME AS CUST_LST_NM,
CUSTOMER1.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM CUSTOMER_ADDR
INNER JOIN (
SELECT /*+ INDEX(CUSTOMER XPKCUSTOMER) +*/
FROM
CUSTOMER
WHERE
CUSTOMER_ID IN (
SELECT CUSTOMER_ID /*+ INDEX(CUSTOMER_ADDR XIE1CUSTOMER_ADDR) +*/
FROM CUSTOMER_ADDR
WHERE (CUSTOMER_ADDR.POSTAL_CD = postalCode OR CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue)
AND CUSTOMER_ADDR.IS_PRIMARY = 1
AND Is_Deleted = 0
) CUSTOMER1
ON CUSTOMER1.CUSTOMER_ID = CUSTOMER_ADDR.CUSTOMER_ID
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
WHERE (CUSTOMER_ADDR.POSTAL_CD = postalCode OR CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue) -- search on exact match speeds up search on LIKE
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer1.Customer_ID
AND
Alt_Acct_Num <> Customer1.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND ROWNUM <= limitRows
IF lastNameValue IS NOT NULL THEN
OPEN cur_OUT FOR
SELECT DISTINCT /*+ INDEX(CUSTOMER_ADDR XIE1CUSTOMER_ADDR) */ /* FIRST_ROWS(100) +*/
CUSTOMER1.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer1.Customer_ID
AND
Alt_Acct_Num <> Customer1.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
NULL -- CUSTOMER1.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER1.LAST_NAME AS CUST_LST_NM,
CUSTOMER1.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM CUSTOMER_ADDR
INNER JOIN (
SELECT /*+ INDEX(CUSTOMER XPKCUSTOMER) +*/
FROM
CUSTOMER
WHERE
CUSTOMER_ID IN (
SELECT CUSTOMER_ID /*+ INDEX(CUSTOMER_ADDR XIE1CUSTOMER_ADDR) +*/
FROM CUSTOMER_ADDR
WHERE (CUSTOMER_ADDR.POSTAL_CD = postalCode OR CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue)
AND CUSTOMER_ADDR.IS_PRIMARY = 1
AND Is_Deleted = 0
) CUSTOMER1
ON CUSTOMER1.CUSTOMER_ID = CUSTOMER_ADDR.CUSTOMER_ID
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
WHERE (CUSTOMER_ADDR.POSTAL_CD = postalCode OR CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue) -- search on exact match speeds up search on LIKE
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
AND (CUSTOMER1.LAST_NAME LIKE lastNameValue) -- RESTRICT ONLY IF A LAST NAME IS SUPPLIED
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer1.Customer_ID
AND
Alt_Acct_Num <> Customer1.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND ROWNUM <= limitRows
END IF;
IF firstNameValue IS NOT NULL THEN
OPEN cur_OUT FOR
SELECT DISTINCT /*+ INDEX(CUSTOMER_ADDR XIE1CUSTOMER_ADDR) */ /* FIRST_ROWS(100) +*/
CUSTOMER1.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer1.Customer_ID
AND
Alt_Acct_Num <> Customer1.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
NULL -- CUSTOMER1.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER1.LAST_NAME AS CUST_LST_NM,
CUSTOMER1.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM CUSTOMER_ADDR
INNER JOIN (
SELECT /*+ INDEX(CUSTOMER XPKCUSTOMER) +*/
FROM
CUSTOMER
WHERE
CUSTOMER_ID IN (
SELECT CUSTOMER_ID /*+ INDEX(CUSTOMER_ADDR XIE1CUSTOMER_ADDR) +*/
FROM CUSTOMER_ADDR
WHERE (CUSTOMER_ADDR.POSTAL_CD = postalCode OR CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue)
AND CUSTOMER_ADDR.IS_PRIMARY = 1
AND Is_Deleted = 0
) CUSTOMER1
ON CUSTOMER1.CUSTOMER_ID = CUSTOMER_ADDR.CUSTOMER_ID
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
WHERE (CUSTOMER_ADDR.POSTAL_CD = postalCode OR CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue) -- search on exact match speeds up search on LIKE
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
AND (CUSTOMER1.FIRST_NAME LIKE firstNameValue) --RESTRICT ONLY IF A FIRST NAME IS SUPPLIED
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer1.Customer_ID
AND
Alt_Acct_Num <> Customer1.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND ROWNUM <= limitRows
END IF;
ELSE
-- name(s) only
IF firstNameValue IS NOT NULL THEN
IF lastNameValue IS NOT NULL THEN
-- first name and last name
OPEN cur_OUT FOR
SELECT DISTINCT /*+ INDEX(CUSTOMER XIE5CUSTOMER) */ /* FIRST_ROWS(100) +*/
CUSTOMER.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
NULL -- CUSTOMER.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER.LAST_NAME AS CUST_LST_NM,
CUSTOMER.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM CUSTOMER
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN CUSTOMER_ADDR
ON CUSTOMER_ADDR.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
WHERE (CUSTOMER.FIRST_NAME = UPPER(firstName) OR CUSTOMER.FIRST_NAME LIKE firstNameValue)
AND (CUSTOMER.LAST_NAME = UPPER(lastName) OR CUSTOMER.LAST_NAME LIKE lastNameValue) -- search on exact match speeds up search on LIKE
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND Is_Deleted = 0
AND ROWNUM <= limitRows
ELSE
-- first name only
OPEN cur_OUT FOR
SELECT DISTINCT /*+ INDEX(CUSTOMER XIE5CUSTOMER) */ /* FIRST_ROWS(100) +*/
CUSTOMER.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
NULL -- CUSTOMER.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER.LAST_NAME AS CUST_LST_NM,
CUSTOMER.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM CUSTOMER
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN CUSTOMER_ADDR
ON CUSTOMER_ADDR.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
WHERE (CUSTOMER.FIRST_NAME = UPPER(firstName) OR CUSTOMER.FIRST_NAME LIKE firstNameValue) -- search on exact match speeds up search on LIKE
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND Is_Deleted = 0
AND ROWNUM <= limitRows
END IF;
ELSE
-- last name only
OPEN cur_OUT FOR
SELECT DISTINCT /*+ INDEX(CUSTOMER XIE6CUSTOMER) */ /* FIRST_ROWS(100) +*/
CUSTOMER.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
NULL -- CUSTOMER.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER.LAST_NAME AS CUST_LST_NM,
CUSTOMER.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM CUSTOMER
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN CUSTOMER_ADDR
ON CUSTOMER_ADDR.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
WHERE (CUSTOMER.LAST_NAME = UPPER(lastName) OR CUSTOMER.LAST_NAME LIKE lastNameValue) -- search on exact match speeds up search on LIKE
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND Is_Deleted = 0
AND ROWNUM <= limitRows
END IF;
END IF;
END IF;
END IF;
END IF;
END SP_SEARCH_CUSTOMERS_BASIC;
-- The tables involved have over 17 million rows and the stats are gathered at 100%
-- using:
EXECUTE DBMS_STATS.gather_schema_stats(ownname=>'CRM', degree=>4, cascade=>TRUE);
-- The table definitions are as follows:
-- CUSTOMER TABLE
Name Null? Type
CUSTOMER_ID NUMBER(38)
CUSTOMER_ACCT_NUM NVARCHAR2(20)
ACCOUNT_TYPE_ID NUMBER(38)
ACCT_STATUS NUMBER(1)
STATUS_EFFECTIVE_DATE DATE
SHARED_ADDRESS_ID NUMBER(38)
MEMBERSHIP_ITEM_ID NUMBER(38)
MEMBERSHIP_WARNING_DATE DATE
MEMBERSHIP_EXPIRATION_DATE DATE
DISCOUNT_PERCENT NUMBER(5,4)
DISCOUNT_CODE NVARCHAR2(24)
HAS_PLCC NUMBER(1)
IS_EMP NUMBER(1)
IS_EMP_FAMILY_FRIEND NUMBER(1)
BUSINESS_NAME NVARCHAR2(40)
USES_PURCH_ORDER NUMBER(1)
TAX_EXEMPT_USAGE_CD CHAR(1)
TAX_EXEMPT_PROMPT NUMBER(1)
DEFAULT_TAX_ID NVARCHAR2(20)
DEFAULT_TAX_EXPIRATION_DATE DATE
HOUSE_CHARGE_ACCT_NUM NVARCHAR2(64)
NAME_PREFIX NVARCHAR2(40)
FIRST_NAME NVARCHAR2(40)
MIDDLE_NAME NVARCHAR2(40)
LAST_NAME NVARCHAR2(40)
NAME_SUFFIX NVARCHAR2(40)
NICK_NAME NVARCHAR2(40)
ALT_FIRST_NAME NVARCHAR2(40)
ALT_LAST_NAME NVARCHAR2(40)
FIRST_VISIT_DATE DATE
LAST_VISIT_DATE DATE
LAST_TRANS_LOCATION_ID NUMBER(38)
LAST_CONTACT_DATE DATE
MARKETING_SOURCE_ID NUMBER(38)
RFM_SCORE NUMBER(38)
COUNTRY_CD VARCHAR2(3)
LOCALE_CD VARCHAR2(10)
EMAIL_ADDR NVARCHAR2(64)
EMAIL_ADDR_VALID NUMBER(1)
ALT_EMAIL_ADDR NVARCHAR2(64)
ALT_EMAIL_ADDR_VALID NUMBER(1)
BIRTH_DATE DATE
BIRTH_DAY DATE
ANNIVERSARY_DATE DATE
ANNIVERSARY_DAY DATE
HOUSEHOLD_COUNT_ID NUMBER(38)
INCOME_RANGE_ID NUMBER(38)
GENDER_ID NUMBER(38)
MARITAL_STATUS_ID NUMBER(38)
EDUCATION_LEVEL_ID NUMBER(38)
HOUSING_TYPE_ID NUMBER(38)
AGE_RANGE_ID NUMBER(38)
LIFETIME_VALUE_SCORE_ID NUMBER(38)
RELIGIOUS_AFFIL_ID NUMBER(38)
DEMOGRAPHIC_ROLE_ID NUMBER(38)
LIFECYCLE_TYPE_ID NUMBER(38)
ACQUISITION_DATE DATE
ACQUISITION_SALES_CHANNEL_ID NUMBER(38)
ACQUISITION_LOCATION_ID NUMBER(38)
SALESPERSON_ID NUMBER(38)
ALT_SALESPERSON_ID NUMBER(38)
HOME_LOCATION_ID NUMBER(38)
ALT_LOCATION_ID NUMBER(38)
CUSTOMER_LOGIN_NAME NVARCHAR2(18)
NAME_LAST_UPDATED_DATE DATE
ATTRBT_LAST_UPDATED_DATE DATE
ATTRBT_UPDATED_BY NVARCHAR2(20)
CREATED_BY NVARCHAR2(40)
CREATED_DATE DATE
LAST_UPDATED_BY NVARCHAR2(40)
LAST_UPDATED_DATE DATE
IS_DELETED NUMBER(1)
CREATE_MODIFY_TIMESTAMP TIMESTAMP(6)
-- INDEXES:
CREATE UNIQUE INDEX "CRM"."XAK1CUSTOMER" ON "CRM"."CUSTOMER" ("CUSTOMER_ACCT_NUM")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUSTIX"
CREATE INDEX "CRM"."XIE5CUSTOMER" ON "CRM"."CUSTOMER" ("FIRST_NAME")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUSTIX"
CREATE INDEX "CRM"."XIE6CUSTOMER" ON "CRM"."CUSTOMER" ("LAST_NAME")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUSTIX"
CREATE INDEX "CRM"."XIE8CUSTOMER" ON "CRM"."CUSTOMER" ("IS_DELETED", "CUSTOMER_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUSTIX"
CREATE INDEX "CRM"."XIF11CUSTOMER" ON "CRM"."CUSTOMER" ("ACQUISITION_LOCATION_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUSTIX"
CREATE INDEX "CRM"."XIF19CUSTOMER" ON "CRM"."CUSTOMER" ("HOME_LOCATION_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUSTIX"
CREATE INDEX "CRM"."XIF22CUSTOMER" ON "CRM"."CUSTOMER" ("SALESPERSON_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUSTIX"
CREATE INDEX "CRM"."XIF24CUSTOMER" ON "CRM"."CUSTOMER" ("ALT_SALESPERSON_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUSTIX"
CREATE INDEX "CRM"."XIF35CUSTOMER" ON "CRM"."CUSTOMER" ("ACCOUNT_TYPE_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUSTIX"
CREATE INDEX "CRM"."XIF37CUSTOMER" ON "CRM"."CUSTOMER" ("ACCT_STATUS")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUSTIX"
CREATE UNIQUE INDEX "CRM"."XPKCUSTOMER" ON "CRM"."CUSTOMER" ("CUSTOMER_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 32768 NEXT 32768 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMREF"
;-- CUSTOMER_ADDR TABLE
Name Null? Type
CUSTOMER_ID NUMBER(38)
ADDRESS_TYPE_ID NUMBER(38)
ADDRESS1 NVARCHAR2(40)
ADDRESS2 NVARCHAR2(40)
ADDRESS3 NVARCHAR2(40)
CITY NVARCHAR2(40)
STATE_CD NVARCHAR2(20)
POSTAL_CD NVARCHAR2(10)
COUNTRY_CD VARCHAR2(3)
REGION_ID NUMBER(38)
MARKETING_SOURCE_ID NUMBER(38)
IS_PRIMARY NUMBER(1)
IS_VALID NUMBER(1)
CANNOT_STANDARDIZE NUMBER(1)
IS_STANDARDIZED NUMBER(1)
STANDARDIZED_DATE DATE
CREATED_DATE DATE
CREATED_BY NVARCHAR2(40)
LAST_UPDATED_BY NVARCHAR2(40)
LAST_UPDATED_DATE DATE
CREATE_MODIFY_TIMESTAMP TIMESTAMP(6)
-- INDEXES
CREATE INDEX "CRM"."XIF1CUSTOMER_ADDR" ON "CRM"."CUSTOMER_ADDR" ("CUSTOMER_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUST02IX"
CREATE INDEX "CRM"."XIF3CUSTOMER_ADDR" ON "CRM"."CUSTOMER_ADDR" ("COUNTRY_CD")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUST02IX"
CREATE INDEX "CRM"."XIF4CUSTOMER_ADDR" ON "CRM"."CUSTOMER_ADDR" ("MARKETING_SOURCE_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUST02IX"
CREATE INDEX "CRM"."XIF7CUSTOMER_ADDR" ON "CRM"."CUSTOMER_ADDR" ("ADDRESS_TYPE_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUST02IX"
CREATE INDEX "CRM"."XIF5CUSTOMER_ADDR" ON "CRM"."CUSTOMER_ADDR" ("STATE_CD")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUST02IX"
CREATE INDEX "CRM"."XIF6CUSTOMER_ADDR" ON "CRM"."CUSTOMER_ADDR" ("REGION_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUST02IX"
CREATE INDEX "CRM"."XIE1CUSTOMER_ADDR" ON "CRM"."CUSTOMER_ADDR" ("POSTAL_CD")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUST02IX"
CREATE INDEX "CRM"."XIE2CUSTOMER_ADDR" ON "CRM"."CUSTOMER_ADDR" ("CITY")
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
STORAGE(INITIAL 4194304 NEXT 4194304 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMCUST02IX"
CREATE UNIQUE INDEX "CRM"."XPKCUSTOMER_ADDR" ON "CRM"."CUSTOMER_ADDR" ("CUSTOMER_ID", "ADDRESS_TYPE_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 32768 NEXT 32768 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "RCRMREF"
--Here is the trace I generated from the above call:
Dump file c:\oracle\ora92\rdbms\trace\rcrm_ora_2972.trc
Fri Feb 01 09:38:58 2008
ORACLE V9.2.0.8.0 - Production vsnsta=0
vsnsql=12 vsnxtr=3
Windows 2000 Version 5.1 Service Pack 2, CPU type 586
Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.8.0 - Production
Windows 2000 Version 5.1 Service Pack 2, CPU type 586
Instance name: rcrm
Redo thread mounted by this instance: 1
Oracle process number: 8
Windows thread id: 2972, image: ORACLE.EXE
*** SESSION ID:(7.22) 2008-02-01 09:38:58.153
APPNAME mod='sqlplus.exe' mh=0 act='' ah=0
=====================
PARSING IN CURSOR #3 len=68 dep=2 uid=0 oct=42 lid=0 tim=9107212774 hv=3578875395 ad='33486e50'
ALTER SESSION SET EVENTS '10046 trace name context forever, level 8'
END OF STMT
EXEC #3:c=0,e=32,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=4,tim=9107206156
=====================
PARSING IN CURSOR #3 len=34 dep=2 uid=0 oct=42 lid=0 tim=9107214996 hv=4177740527 ad='33485964'
ALTER SESSION SET SQL_TRACE = TRUE
END OF STMT
PARSE #3:c=0,e=29,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=4,tim=9107214992
EXEC #3:c=0,e=23,p=0,cr=0,cu=0,mis=0,r=0,dep=2,og=4,tim=9107217127
=====================
PARSING IN CURSOR #1 len=364 dep=1 uid=0 oct=47 lid=0 tim=9107217592 hv=133124521 ad='33487c5c'
DECLARE
A VARCHAR2(200);
BEGIN
IF SYS_CONTEXT('USERENV','SESSION_USER') = 'CRM'
THEN
A := 'ALTER SESSION SET TIMED_STATISTICS = TRUE';
EXECUTE IMMEDIATE A ;
A := 'ALTER SESSION SET EVENTS ''10046 trace name context forever, level 8''' ;
EXECUTE IMMEDIATE A ;
A := 'ALTER SESSION SET SQL_TRACE = TRUE' ;
EXECUTE IMMEDIATE A ;
END IF;
END;
END OF STMT
EXEC #1:c=0,e=49410,p=1,cr=3,cu=0,mis=0,r=1,dep=1,og=4,tim=9107217587
=====================
PARSING IN CURSOR #1 len=22 dep=0 uid=21 oct=3 lid=21 tim=9107226188 hv=4119976668 ad='33483e64'
SELECT USER FROM DUAL
END OF STMT
PARSE #1:c=0,e=42,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=9107226183
EXEC #1:c=0,e=27,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=9107228691
FETCH #1:c=0,e=47,p=0,cr=3,cu=0,mis=0,r=1,dep=0,og=1,tim=9107229270
STAT #1 id=1 cnt=1 pid=0 pos=1 obj=222 op='TABLE ACCESS FULL DUAL '
=====================
PARSING IN CURSOR #1 len=31 dep=0 uid=21 oct=47 lid=21 tim=9107230515 hv=2865022085 ad='33451edc'
BEGIN DBMS_OUTPUT.DISABLE; END;
END OF STMT
PARSE #1:c=0,e=41,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=9107230512
EXEC #1:c=0,e=94,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,tim=9107232725
=====================
PARSING IN CURSOR #1 len=161 dep=0 uid=21 oct=3 lid=21 tim=9107234862 hv=3226991418 ad='3344f0a8'
SELECT ATTRIBUTE,SCOPE,NUMERIC_VALUE,CHAR_VALUE,DATE_VALUE FROM SYSTEM.PRODUCT_PRIVS WHERE (UPPER(:"SYS_B_0") LIKE UPPER(PRODUCT)) AND (UPPER(USER) LIKE USERID)
END OF STMT
PARSE #1:c=0,e=106,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=9107234859
EXEC #1:c=0,e=28,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=9107237071
FETCH #1:c=0,e=30,p=0,cr=3,cu=0,mis=0,r=0,dep=0,og=1,tim=9107237621
STAT #1 id=1 cnt=0 pid=0 pos=1 obj=5932 op='TABLE ACCESS FULL SQLPLUS_PRODUCT_PROFILE '
=====================
PARSING IN CURSOR #1 len=188 dep=0 uid=21 oct=3 lid=21 tim=9107238984 hv=1054999632 ad='333ebb04'
SELECT CHAR_VALUE FROM SYSTEM.PRODUCT_PRIVS WHERE (UPPER(:"SYS_B_0") LIKE UPPER(PRODUCT)) AND ((UPPER(USER) LIKE USERID) OR (USERID = :"SYS_B_1")) AND (UPPER(ATTRIBUTE) = :"SYS_B_2")
END OF STMT
PARSE #1:c=0,e=87,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=9107238980
EXEC #1:c=0,e=28,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=9107241367
FETCH #1:c=0,e=19,p=0,cr=3,cu=0,mis=0,r=0,dep=0,og=1,tim=9107241909
STAT #1 id=1 cnt=0 pid=0 pos=1 obj=5932 op='TABLE ACCESS FULL SQLPLUS_PRODUCT_PROFILE '
=====================
PARSING IN CURSOR #1 len=54 dep=0 uid=21 oct=47 lid=21 tim=9107243082 hv=1432236634 ad='333e77cc'
BEGIN DBMS_APPLICATION_INFO.SET_MODULE(:1,NULL); END;
END OF STMT
PARSE #1:c=0,e=37,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=9107243078
APPNAME mod='SQL*Plus' mh=3669949024 act='' ah=4029777240
EXEC #1:c=0,e=522,p=0,cr=0,cu=0,mis=0,r=1,dep=0,og=1,tim=9107245734
=====================
PARSING IN CURSOR #1 len=68 dep=0 uid=21 oct=3 lid=21 tim=9107246444 hv=112077794 ad='333e47e4'
SELECT DECODE(:"SYS_B_0",:"SYS_B_1",:"SYS_B_2",:"SYS_B_3") FROM DUAL
END OF STMT
PARSE #1:c=0,e=56,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=9107246440
EXEC #1:c=0,e=19,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=9107248619
FETCH #1:c=0,e=36,p=0,cr=3,cu=0,mis=0,r=1,dep=0,og=1,tim=9107249097
STAT #1 id=1 cnt=1 pid=0 pos=1 obj=222 op='TABLE ACCESS FULL DUAL '
XCTEND rlbk=0, rd_only=1
=====================
PARSING IN CURSOR #1 len=96 dep=0 uid=21 oct=47 lid=21 tim=9116278253 hv=151722859 ad='331867f8'
BEGIN SP_SEARCH_CUSTOMERS_BASIC(NULL, 'miller', NULL, NULL, NULL, NULL, '06413', :V1, 0); END;
END OF STMT
PARSE #1:c=0,e=115,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=9116278245
=====================
PARSING IN CURSOR #3 len=1557 dep=1 uid=21 oct=3 lid=21 tim=9116282628 hv=3730552002 ad='333adb04'
SELECT DISTINCT /*+ INDEX(CUSTOMER_ADDR XIE1CUSTOMER_ADDR) */ /* FIRST_ROWS(100) */ CUSTOMER1.CUSTOMER_ID AS PREFERRED_CUST_KEY, COALESCE( ( SELECT MIN(ALT_ACCT_NUM) FROM ADDITIONAL_ACCOUNT WHERE ADDITIONAL_ACCOUNT.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID AND ALT_ACCT_NUM <> CUSTOMER1.CUSTOMER_ACCT_NUM AND ALT_ACCT_NUM LIKE :B5 ), NULL ) AS CUST_ID, CUSTOMER1.LAST_NAME AS CUST_LST_NM, CUSTOMER1.FIRST_NAME AS CUST_FRST_NM, CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE, CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE, CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP FROM CUSTOMER_ADDR INNER JOIN ( SELECT /* INDEX(CUSTOMER XPKCUSTOMER) */ * FROM CUSTOMER WHERE CUSTOMER_ID IN ( SELECT CUSTOMER_ID /* INDEX(CUSTOMER_ADDR XIE1CUSTOMER_ADDR) +*/ FROM CUSTOMER_ADDR WHERE (CUSTOMER_ADDR.POSTAL_CD = :B2 OR CUSTOMER_ADDR.POSTAL_CD LIKE :B1 ) AND CUSTOMER_ADDR.IS_PRIMARY = 1 ) AND IS_DELETED = 0 ) CUSTOMER1 ON CUSTOMER1.CUSTOMER_ID = CUSTOMER_ADDR.CUSTOMER_ID LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID AND CUSTOMER
Okay, sorry I should have provided the tkprof report instead. I have changed the query to ommit the hints and made some changes to the where clause based on comments above. I have also changed CURSOR_SHARING to EXACT. Here is the new query with all my changes along with the tkprof report. It seem to be much faster.
CREATE OR REPLACE PROCEDURE "CRM"."SP_SEARCH_CUSTOMERS_BASIC" (
customerAcctNum IN NVARCHAR2,
lastName IN NVARCHAR2,
firstName IN NVARCHAR2,
homePhone IN VARCHAR2,
workPhone IN VARCHAR2,
associateNumber IN NVARCHAR2,
postalCode IN NVARCHAR2,
cur_OUT IN OUT SYS_REFCURSOR,
filterAltAccountOnly IN INTEGER := 0 -- nonzero = only return customers having preferred alt ID
IS
customerId NUMBER;
lastNameValue NVARCHAR2(45);
firstNameValue NVARCHAR2(45);
homePhoneValue VARCHAR2(30);
workPhoneValue VARCHAR2(30);
postalCodeValue NVARCHAR2(15);
limitRows NUMBER := 100; -- limit result set size for performance
-- TODO: take this from a config
preferredAltIDFormat VARCHAR2(30) := '7_____________'; -- 14 digits, first digit always 7
BEGIN
-- Initialize variables!
lastNameValue := NULL;
firstNameValue := NULL;
homePhoneValue := NULL;
workPhoneValue := NULL;
postalCodeValue := NULL;
IF lastName IS NOT NULL THEN
lastNameValue := UPPER(lastName) || '%';
END IF;
IF firstName IS NOT NULL THEN
firstNameValue := UPPER(firstName) || '%';
END IF;
IF homePhone IS NOT NULL THEN
homePhoneValue := homePhone;
END IF;
IF workPhone IS NOT NULL THEN
workPhoneValue := workPhone;
END IF;
IF postalCode IS NOT NULL THEN
postalCodeValue := postalCode || '%';
END IF;
-- Writing a single query that is efficient for all cases is non-trivial.
-- Break the cases out into a few subcases and let them be analyzed separately.
IF customerAcctNum IS NOT NULL THEN
-- Getting the ID separately, instead of through an additional inner join on the select, is faster
customerId := FN_GET_CUSTOMER_ID(customerAcctNum);--VALID CUSTOMER NUMBER IS EXPECTED
OPEN cur_OUT FOR
SELECT DISTINCT -- /*+ INDEX(CUSTOMER XPKCUSTOMER) +*/
CUSTOMER.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
-- SELECT
-- MIN(Alt_Acct_Num)
-- FROM
-- Additional_Account
-- WHERE
-- Additional_Account.Customer_ID = Customer.Customer_ID
-- AND
-- Alt_Acct_Num <> Customer.Customer_Acct_Num
-- AND
-- Alt_Acct_Num NOT LIKE preferredAltIDFormat
-- AND
-- LENGTH(Alt_Acct_Num) < 24 -- Omit base64'd hashes
NULL -- customerAcctNum
) AS CUST_ID,
CUSTOMER.LAST_NAME AS CUST_LST_NM,
CUSTOMER.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM CUSTOMER
LEFT OUTER JOIN ASSOCIATE -- Could have a customer without an associate
ON ASSOCIATE.ASSOCIATE_ID = CUSTOMER.SALESPERSON_ID
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN CUSTOMER_ADDR
ON CUSTOMER_ADDR.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
WHERE CUSTOMER.CUSTOMER_ID = customerId
AND (ASSOCIATE.ASSOCIATE_NUMBER = associateNumber OR associateNumber IS NULL) --RESTRICT ONLY IF AN ASSOCIATE NUMBER IS SUPPLIED
AND (CUSTOMER.LAST_NAME LIKE lastNameValue OR lastNameValue IS NULL) -- RESTRICT ONLY IF A LAST NAME IS SUPPLIED
AND (CUSTOMER.FIRST_NAME LIKE firstNameValue OR firstNameValue IS NULL) --RESTRICT ONLY IF A FIRST NAME IS SUPPLIED
AND (CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue OR postalCodeValue IS NULL) --RESTRICT ONLY IF A POSTAL CODE IS SUPPLIED
AND (CUSTOMER_HOME_PHONE.PHONE_NUM = homePhoneValue OR homePhoneValue IS NULL) --RESTRICT ONLY IF A HOME PHONE NUMBER IS SUPPLIED
AND (CUSTOMER_WORK_PHONE.PHONE_NUM = workPhoneValue OR workPhoneValue IS NULL) --RESTRICT ONLY IF A WORK PHONE NUMBER IS SUPPLIED
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND Is_Deleted = 0
AND ROWNUM <= limitRows
ELSE
-- customerAcctNum IS NULL
IF associateNumber IS NOT NULL THEN
OPEN cur_OUT FOR
SELECT DISTINCT --/*+ INDEX(CUSTOMER XIF22CUSTOMER) */ /* FIRST_ROWS (100) +*/
CUSTOMER.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
-- SELECT
-- MIN(Alt_Acct_Num)
-- FROM
-- Additional_Account
-- WHERE
-- Additional_Account.Customer_ID = Customer.Customer_ID
-- AND
-- Alt_Acct_Num <> Customer.Customer_Acct_Num
-- AND
-- Alt_Acct_Num NOT LIKE preferredAltIDFormat
-- AND
-- LENGTH(Alt_Acct_Num) < 24 -- Omit base64'd hashes
NULL -- CUSTOMER.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER.LAST_NAME AS CUST_LST_NM,
CUSTOMER.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM ASSOCIATE
INNER JOIN CUSTOMER
ON CUSTOMER.SALESPERSON_ID = ASSOCIATE.ASSOCIATE_ID
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN CUSTOMER_ADDR
ON CUSTOMER_ADDR.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple add resses - there is no enforcement of "only one Is_Primary per customer"
WHERE ASSOCIATE.ASSOCIATE_NUMBER = associateNumber
AND (CUSTOMER.LAST_NAME LIKE lastNameValue OR lastNameValue IS NULL) -- RESTRICT ONLY IF A LAST NAME IS SUPPLIED
AND (CUSTOMER.FIRST_NAME LIKE firstNameValue OR firstNameValue IS NULL) --RESTRICT ONLY IF A FIRST NAME IS SUPPLIED
AND (CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue OR postalCodeValue IS NULL) --RESTRICT ONLY IF A POSTAL CODE IS SUPPLIED
AND (CUSTOMER_HOME_PHONE.PHONE_NUM = homePhoneValue OR homePhoneValue IS NULL) --RESTRICT ONLY IF A HOME PHONE NUMBER IS SUPPLIED
AND (CUSTOMER_WORK_PHONE.PHONE_NUM = workPhoneValue OR workPhoneValue IS NULL) --RESTRICT ONLY IF A WORK PHONE NUMBER IS SUPPLIED
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND Is_Deleted = 0
AND ROWNUM <= limitRows
ELSE
-- customerAcctNum IS NULL AND associateNumber IS NULL
IF homePhoneValue IS NOT NULL OR workPhoneValue IS NOT NULL THEN
OPEN cur_OUT FOR
SELECT DISTINCT --/*+ INDEX(PHONE XIE2PHONE) */ /* FIRST_ROWS(100) +*/
CUSTOMER1.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer1.Customer_ID
AND
Alt_Acct_Num <> Customer1.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
-- SELECT
-- MIN(Alt_Acct_Num)
-- FROM
-- Additional_Account
-- WHERE
-- Additional_Account.Customer_ID = Customer1.Customer_ID
-- AND
-- Alt_Acct_Num <> Customer1.Customer_Acct_Num
-- AND
-- Alt_Acct_Num NOT LIKE preferredAltIDFormat
-- AND
-- LENGTH(Alt_Acct_Num) < 24 -- Omit base64'd hashes
NULL -- CUSTOMER1.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER1.LAST_NAME AS CUST_LST_NM,
CUSTOMER1.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM PHONE ALL_PHONE
INNER JOIN (
SELECT --/*+ INDEX(CUSTOMER XPKCUSTOMER) +*/
FROM
CUSTOMER
WHERE
CUSTOMER_ID IN (
SELECT CUSTOMER_ID --/*+ INDEX(PHONE XIE2PHONE) +*/
FROM PHONE
WHERE (PHONE.PHONE_NUM IN (homePhoneValue, workPhoneValue)) -- indexed query
AND Is_Deleted = 0
) CUSTOMER1
ON CUSTOMER1.CUSTOMER_ID = ALL_PHONE.CUSTOMER_ID
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN CUSTOMER_ADDR
ON CUSTOMER_ADDR.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
WHERE (ALL_PHONE.PHONE_NUM = homePhoneValue OR ALL_PHONE.PHONE_NUM = workPhoneValue) -- indexed query
AND (CUSTOMER1.LAST_NAME LIKE lastNameValue OR lastNameValue IS NULL) -- RESTRICT ONLY IF A LAST NAME IS SUPPLIED
AND (CUSTOMER1.FIRST_NAME LIKE firstNameValue OR firstNameValue IS NULL) --RESTRICT ONLY IF A FIRST NAME IS SUPPLIED
AND (CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue OR postalCodeValue IS NULL) --RESTRICT ONLY IF A POSTAL CODE IS SUPPLIED
AND (CUSTOMER_HOME_PHONE.PHONE_NUM = homePhoneValue OR homePhoneValue IS NULL) --RESTRICT ONLY IF A HOME PHONE NUMBER IS SUPPLIED
AND (CUSTOMER_WORK_PHONE.PHONE_NUM = workPhoneValue OR workPhoneValue IS NULL) --RESTRICT ONLY IF A WORK PHONE NUMBER IS SUPPLIED
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer1.Customer_ID
AND
Alt_Acct_Num <> Customer1.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND ROWNUM <= limitRows
ELSE
-- customerAcctNum IS NULL AND associateNumber IS NULL AND phone numbers are null
IF postalCodeValue IS NOT NULL THEN
OPEN cur_OUT FOR
SELECT DISTINCT --/*+ INDEX(CUSTOMER_ADDR XIE1CUSTOMER_ADDR) */ /* FIRST_ROWS(100) +*/
CUSTOMER1.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer1.Customer_ID
AND
Alt_Acct_Num <> Customer1.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
-- SELECT
-- MIN(Alt_Acct_Num)
-- FROM
-- Additional_Account
-- WHERE
-- Additional_Account.Customer_ID = Customer1.Customer_ID
-- AND
-- Alt_Acct_Num <> Customer1.Customer_Acct_Num
-- AND
-- Alt_Acct_Num NOT LIKE preferredAltIDFormat
-- AND
-- LENGTH(Alt_Acct_Num) < 24 -- Omit base64'd hashes
NULL -- CUSTOMER1.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER1.LAST_NAME AS CUST_LST_NM,
CUSTOMER1.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM CUSTOMER_ADDR
INNER JOIN (
SELECT --/*+ INDEX(CUSTOMER XPKCUSTOMER) +*/
FROM
CUSTOMER
WHERE
CUSTOMER_ID IN (
SELECT CUSTOMER_ID --/*+ INDEX(CUSTOMER_ADDR XIE1CUSTOMER_ADDR) +*/
FROM CUSTOMER_ADDR
WHERE (CUSTOMER_ADDR.POSTAL_CD = postalCode OR CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue)
AND CUSTOMER_ADDR.IS_PRIMARY = 1
AND Is_Deleted = 0
) CUSTOMER1
ON CUSTOMER1.CUSTOMER_ID = CUSTOMER_ADDR.CUSTOMER_ID
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
WHERE (CUSTOMER_ADDR.POSTAL_CD = postalCode OR CUSTOMER_ADDR.POSTAL_CD LIKE postalCodeValue) -- search on exact match speeds up search on LIKE
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
AND (CUSTOMER1.LAST_NAME LIKE lastNameValue OR lastNameValue IS NULL) -- RESTRICT ONLY IF A LAST NAME IS SUPPLIED
AND (CUSTOMER1.FIRST_NAME LIKE firstNameValue OR firstNameValue IS NULL) --RESTRICT ONLY IF A FIRST NAME IS SUPPLIED
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer1.Customer_ID
AND
Alt_Acct_Num <> Customer1.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND ROWNUM <= limitRows
ELSE
-- name(s) only
IF firstNameValue IS NOT NULL THEN
IF lastNameValue IS NOT NULL THEN
-- first name and last name
OPEN cur_OUT FOR
SELECT DISTINCT --/*+ INDEX(CUSTOMER XIE5CUSTOMER) */ /* FIRST_ROWS(100) +*/
CUSTOMER.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
-- SELECT
-- MIN(Alt_Acct_Num)
-- FROM
-- Additional_Account
-- WHERE
-- Additional_Account.Customer_ID = Customer.Customer_ID
-- AND
-- Alt_Acct_Num <> Customer.Customer_Acct_Num
-- AND
-- Alt_Acct_Num NOT LIKE preferredAltIDFormat
-- AND
-- LENGTH(Alt_Acct_Num) < 24 -- Omit base64'd hashes
NULL -- CUSTOMER.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER.LAST_NAME AS CUST_LST_NM,
CUSTOMER.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM CUSTOMER
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN CUSTOMER_ADDR
ON CUSTOMER_ADDR.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
-- WHERE (CUSTOMER.FIRST_NAME = UPPER(firstName) OR CUSTOMER.FIRST_NAME LIKE firstNameValue)
-- AND (CUSTOMER.LAST_NAME = UPPER(lastName) OR CUSTOMER.LAST_NAME LIKE lastNameValue) -- search on exact match speeds up search on LIKE
WHERE (CUSTOMER.FIRST_NAME LIKE firstNameValue)
AND (CUSTOMER.LAST_NAME LIKE lastNameValue) -- search on exact match speeds up search on LIKE
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND Is_Deleted = 0
AND ROWNUM <= limitRows
ELSE
-- first name only
OPEN cur_OUT FOR
SELECT DISTINCT --/*+ INDEX(CUSTOMER XIE5CUSTOMER) */ /* FIRST_ROWS(100) +*/
CUSTOMER.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
-- SELECT
-- MIN(Alt_Acct_Num)
-- FROM
-- Additional_Account
-- WHERE
-- Additional_Account.Customer_ID = Customer.Customer_ID
-- AND
-- Alt_Acct_Num <> Customer.Customer_Acct_Num
-- AND
-- Alt_Acct_Num NOT LIKE preferredAltIDFormat
-- AND
-- LENGTH(Alt_Acct_Num) < 24 -- Omit base64'd hashes
NULL -- CUSTOMER.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER.LAST_NAME AS CUST_LST_NM,
CUSTOMER.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM CUSTOMER
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN CUSTOMER_ADDR
ON CUSTOMER_ADDR.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
-- WHERE (CUSTOMER.FIRST_NAME = UPPER(firstName) OR CUSTOMER.FIRST_NAME LIKE firstNameValue) -- search on exact match speeds up search on LIKE
WHERE (CUSTOMER.FIRST_NAME LIKE firstNameValue) -- search on exact match speeds up search on LIKE
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND Is_Deleted = 0
AND ROWNUM <= limitRows
END IF;
ELSE
-- last name only
OPEN cur_OUT FOR
SELECT DISTINCT --/*+ INDEX(CUSTOMER XIE6CUSTOMER) */ /* FIRST_ROWS(100) +*/
CUSTOMER.CUSTOMER_ID AS PREFERRED_CUST_KEY,
COALESCE(
SELECT
MIN(Alt_Acct_Num)
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
-- SELECT
-- MIN(Alt_Acct_Num)
-- FROM
-- Additional_Account
-- WHERE
-- Additional_Account.Customer_ID = Customer.Customer_ID
-- AND
-- Alt_Acct_Num <> Customer.Customer_Acct_Num
-- AND
-- Alt_Acct_Num NOT LIKE preferredAltIDFormat
-- AND
-- LENGTH(Alt_Acct_Num) < 24 -- Omit base64'd hashes
NULL -- CUSTOMER.CUSTOMER_ACCT_NUM
) AS CUST_ID,
CUSTOMER.LAST_NAME AS CUST_LST_NM,
CUSTOMER.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE,
CUSTOMER_WORK_PHONE.PHONE_NUM AS WORK_PHONE,
CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP
FROM CUSTOMER
LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE
ON CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN PHONE CUSTOMER_WORK_PHONE
ON CUSTOMER_WORK_PHONE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 -- TODO: This should be taken from a config setting
LEFT OUTER JOIN CUSTOMER_ADDR
ON CUSTOMER_ADDR.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
AND CUSTOMER_ADDR.IS_PRIMARY = 1 -- WARNING: May match multiple addresses - there is no enforcement of "only one Is_Primary per customer"
-- WHERE (CUSTOMER.LAST_NAME = UPPER(lastName) OR CUSTOMER.LAST_NAME LIKE lastNameValue) -- search on exact match speeds up search on LIKE
WHERE (CUSTOMER.LAST_NAME LIKE lastNameValue) -- search on exact match speeds up search on LIKE
AND (filterAltAccountOnly = 0 OR EXISTS (
SELECT
FROM
Additional_Account
WHERE
Additional_Account.Customer_ID = Customer.Customer_ID
AND
Alt_Acct_Num <> Customer.Customer_Acct_Num
AND
Alt_Acct_Num LIKE preferredAltIDFormat
AND Is_Deleted = 0
AND ROWNUM <= limitRows
END IF;
END IF;
END IF;
END IF;
END IF;
END SP_SEARCH_CUSTOMERS_BASIC;
-- tkprof report.
TKPROF: Release 9.2.0.8.0 - Production on Fri Feb 1 14:39:23 2008
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Trace file: C:\oracle\ora92\rdbms\trace\rcrm_ora_1876.trc
Sort options: prsela exeela fchela
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
SELECT DISTINCT CUSTOMER1.CUSTOMER_ID AS PREFERRED_CUST_KEY, COALESCE( (
SELECT MIN(ALT_ACCT_NUM)
FROM
ADDITIONAL_ACCOUNT WHERE ADDITIONAL_ACCOUNT.CUSTOMER_ID =
CUSTOMER1.CUSTOMER_ID AND ALT_ACCT_NUM <> CUSTOMER1.CUSTOMER_ACCT_NUM AND
ALT_ACCT_NUM LIKE :B7 ), NULL ) AS CUST_ID, CUSTOMER1.LAST_NAME AS
CUST_LST_NM, CUSTOMER1.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE, CUSTOMER_WORK_PHONE.PHONE_NUM
AS WORK_PHONE, CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP FROM CUSTOMER_ADDR
INNER JOIN ( SELECT * FROM CUSTOMER WHERE CUSTOMER_ID IN ( SELECT
CUSTOMER_ID FROM CUSTOMER_ADDR WHERE (CUSTOMER_ADDR.POSTAL_CD = :B2 OR
CUSTOMER_ADDR.POSTAL_CD LIKE :B1 ) AND CUSTOMER_ADDR.IS_PRIMARY = 1 ) AND
IS_DELETED = 0 ) CUSTOMER1 ON CUSTOMER1.CUSTOMER_ID =
CUSTOMER_ADDR.CUSTOMER_ID LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE ON
CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID AND
CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 LEFT OUTER JOIN PHONE
CUSTOMER_WORK_PHONE ON CUSTOMER_WORK_PHONE.CUSTOMER_ID =
CUSTOMER1.CUSTOMER_ID AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 WHERE
(CUSTOMER_ADDR.POSTAL_CD = :B2 OR CUSTOMER_ADDR.POSTAL_CD LIKE :B1 ) AND
CUSTOMER_ADDR.IS_PRIMARY = 1 AND (CUSTOMER1.LAST_NAME LIKE :B6 OR :B6 IS
NULL) AND (CUSTOMER1.FIRST_NAME LIKE :B5 OR :B5 IS NULL) AND (:B4 = 0 OR
EXISTS ( SELECT * FROM ADDITIONAL_ACCOUNT WHERE
ADDITIONAL_ACCOUNT.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID AND ALT_ACCT_NUM <>
CUSTOMER1.CUSTOMER_ACCT_NUM AND ALT_ACCT_NUM LIKE :B7 ) ) AND ROWNUM <= :B3
call count cpu elapsed disk query current rows
Parse 1 0.04 0.04 0 0 0 0
Execute 1 0.03 0.02 0 0 0 0
Fetch 1 0.03 0.02 0 4123 0 1
total 3 0.10 0.09 0 4123 0 1
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user id: 21 (recursive depth: 1)
Rows Row Source Operation
1 SORT UNIQUE
1 COUNT STOPKEY
1 FILTER
1 NESTED LOOPS OUTER
1 NESTED LOOPS OUTER
1 HASH JOIN SEMI
1 NESTED LOOPS
819 TABLE ACCESS BY INDEX ROWID CUSTOMER_ADDR
819 BITMAP CONVERSION TO ROWIDS
1 BITMAP OR
1 BITMAP CONVERSION FROM ROWIDS
819 INDEX RANGE SCAN XIE1CUSTOMER_ADDR (object id 6843)
1 BITMAP CONVERSION FROM ROWIDS
819 SORT ORDER BY
819 INDEX RANGE SCAN XIE1CUSTOMER_ADDR (object id 6843)
1 TABLE ACCESS BY INDEX ROWID CUSTOMER
819 INDEX UNIQUE SCAN XPKCUSTOMER (object id 6635)
819 TABLE ACCESS BY INDEX ROWID CUSTOMER_ADDR
819 BITMAP CONVERSION TO ROWIDS
1 BITMAP OR
1 BITMAP CONVERSION FROM ROWIDS
819 INDEX RANGE SCAN XIE1CUSTOMER_ADDR (object id 6843)
1 BITMAP CONVERSION FROM ROWIDS
819 SORT ORDER BY
819 INDEX RANGE SCAN XIE1CUSTOMER_ADDR (object id 6843)
0 TABLE ACCESS BY INDEX ROWID PHONE
0 INDEX UNIQUE SCAN XPKPHONE (object id 6727)
1 TABLE ACCESS BY INDEX ROWID PHONE
1 INDEX UNIQUE SCAN XPKPHONE (object id 6727)
0 INDEX RANGE SCAN XPKADDITIONAL_ACCOUNT (object id 6609)
BEGIN SP_SEARCH_CUSTOMERS_BASIC(NULL, 'miller', NULL, NULL, NULL, NULL,
'06413', :V1, 0); END;
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.04 0.05 0 0 0 1
Fetch 0 0.00 0.00 0 0 0 0
total 2 0.04 0.05 0 0 0 1
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user id: 21
SELECT ATTRIBUTE,SCOPE,NUMERIC_VALUE,CHAR_VALUE,DATE_VALUE
FROM
SYSTEM.PRODUCT_PRIVS WHERE (UPPER('SQL*Plus') LIKE UPPER(PRODUCT)) AND
(UPPER(USER) LIKE USERID)
call count cpu elapsed disk query current rows
Parse 1 0.01 0.01 0 3 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 3 0 0
total 3 0.01 0.01 0 6 0 0
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user id: 21
Rows Row Source Operation
0 TABLE ACCESS FULL SQLPLUS_PRODUCT_PROFILE
SELECT CHAR_VALUE
FROM
SYSTEM.PRODUCT_PRIVS WHERE (UPPER('SQL*Plus') LIKE UPPER(PRODUCT)) AND
((UPPER(USER) LIKE USERID) OR (USERID = 'PUBLIC')) AND (UPPER(ATTRIBUTE) =
'ROLES')
call count cpu elapsed disk query current rows
Parse 1 0.01 0.00 0 3 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 3 0 0
total 3 0.01 0.00 0 6 0 0
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user id: 21
Rows Row Source Operation
0 TABLE ACCESS FULL SQLPLUS_PRODUCT_PROFILE
BEGIN DBMS_APPLICATION_INFO.SET_MODULE(:1,NULL); END;
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.01 0.00 0 0 0 1
Fetch 0 0.00 0.00 0 0 0 0
total 2 0.01 0.00 0 0 0 1
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user id: 21
BEGIN DBMS_OUTPUT.DISABLE; END;
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 1
Fetch 0 0.00 0.00 0 0 0 0
total 2 0.00 0.00 0 0 0 1
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user id: 21
SELECT USER
FROM
DUAL
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 1 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 3 0 1
total 3 0.00 0.00 0 4 0 1
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user id: 21
Rows Row Source Operation
1 TABLE ACCESS FULL DUAL
SELECT DECODE('A','A','1','2')
FROM
DUAL
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 1 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 3 0 1
total 3 0.00 0.00 0 4 0 1
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user id: 21
Rows Row Source Operation
1 TABLE ACCESS FULL DUAL
OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
Parse 7 0.03 0.02 0 8 0 0
Execute 7 0.06 0.05 0 0 0 3
Fetch 4 0.00 0.00 0 12 0 2
total 18 0.09 0.08 0 20 0 5
Misses in library cache during parse: 7
OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
Parse 10 0.06 0.05 0 0 0 0
Execute 15 0.03 0.03 0 3 0 2
Fetch 10 0.03 0.02 0 4148 0 10
total 35 0.12 0.11 0 4151 0 12
Misses in library cache during parse: 6
Misses in library cache during execute: 2
8 user SQL statements in session.
12 internal SQL statements in session.
20 SQL statements in session.
Trace file: C:\oracle\ora92\rdbms\trace\rcrm_ora_1876.trc
Trace file compatibility: 9.02.00
Sort options: prsela exeela fchela
1 session in tracefile.
8 user SQL statements in trace file.
12 internal SQL statements in trace file.
20 SQL statements in trace file.
16 unique SQL statements in trace file.
212 lines in trace file.--
A search on just zip code still takes a while but that may not be a reasonable query.
Here is the tkprof for just zip code search:
TKPROF: Release 9.2.0.8.0 - Production on Fri Feb 1 14:52:42 2008
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Trace file: C:\oracle\ora92\rdbms\trace\rcrm_ora_3976.trc
Sort options: prsela exeela fchela
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
SELECT DISTINCT CUSTOMER1.CUSTOMER_ID AS PREFERRED_CUST_KEY, COALESCE( (
SELECT MIN(ALT_ACCT_NUM)
FROM
ADDITIONAL_ACCOUNT WHERE ADDITIONAL_ACCOUNT.CUSTOMER_ID =
CUSTOMER1.CUSTOMER_ID AND ALT_ACCT_NUM <> CUSTOMER1.CUSTOMER_ACCT_NUM AND
ALT_ACCT_NUM LIKE :B7 ), NULL ) AS CUST_ID, CUSTOMER1.LAST_NAME AS
CUST_LST_NM, CUSTOMER1.FIRST_NAME AS CUST_FRST_NM,
CUSTOMER_HOME_PHONE.PHONE_NUM AS HOME_PHONE, CUSTOMER_WORK_PHONE.PHONE_NUM
AS WORK_PHONE, CUSTOMER_ADDR.POSTAL_CD AS CUST_ADDR_ZIP FROM CUSTOMER_ADDR
INNER JOIN ( SELECT * FROM CUSTOMER WHERE CUSTOMER_ID IN ( SELECT
CUSTOMER_ID FROM CUSTOMER_ADDR WHERE (CUSTOMER_ADDR.POSTAL_CD = :B2 OR
CUSTOMER_ADDR.POSTAL_CD LIKE :B1 ) AND CUSTOMER_ADDR.IS_PRIMARY = 1 ) AND
IS_DELETED = 0 ) CUSTOMER1 ON CUSTOMER1.CUSTOMER_ID =
CUSTOMER_ADDR.CUSTOMER_ID LEFT OUTER JOIN PHONE CUSTOMER_HOME_PHONE ON
CUSTOMER_HOME_PHONE.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID AND
CUSTOMER_HOME_PHONE.PHONE_TYPE_ID = 1 LEFT OUTER JOIN PHONE
CUSTOMER_WORK_PHONE ON CUSTOMER_WORK_PHONE.CUSTOMER_ID =
CUSTOMER1.CUSTOMER_ID AND CUSTOMER_WORK_PHONE.PHONE_TYPE_ID = 2 WHERE
(CUSTOMER_ADDR.POSTAL_CD = :B2 OR CUSTOMER_ADDR.POSTAL_CD LIKE :B1 ) AND
CUSTOMER_ADDR.IS_PRIMARY = 1 AND (CUSTOMER1.LAST_NAME LIKE :B6 OR :B6 IS
NULL) AND (CUSTOMER1.FIRST_NAME LIKE :B5 OR :B5 IS NULL) AND (:B4 = 0 OR
EXISTS ( SELECT * FROM ADDITIONAL_ACCOUNT WHERE
ADDITIONAL_ACCOUNT.CUSTOMER_ID = CUSTOMER1.CUSTOMER_ID AND ALT_ACCT_NUM <>
CUSTOMER1.CUSTOMER_ACCT_NUM AND ALT_ACCT_NUM LIKE :B7 ) ) AND ROWNUM <= :B3
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 7 1.14 69.49 11387 16012 0 100
total 9 1.14 69.49 11387 16012 0 100
Misses in library cache during parse: 0
Optimizer goal: ALL_ROWS
Parsing user id: 21 (recursive depth: 1)
Rows Row Source Operation
100 SORT UNIQUE
100 COUNT STOPKEY
100 FILTER
100 NESTED LOOPS OUTER
100 NESTED LOOPS OUTER
100 HASH JOIN SEMI
3797 NESTED LOOPS
3797 TABLE ACCESS BY INDEX ROWID CUSTOMER_ADDR
3797 BITMAP CONVERSION TO ROWIDS
1 BITMAP OR
1 BITMAP CONVERSION FROM ROWIDS
3797 INDEX RANGE SCAN XIE1CUSTOMER_ADDR (object id 6843)
1 BITMAP CONVERSION FROM ROWIDS
3797 SORT ORDER BY
3797 INDEX RANGE SCAN XIE1CUSTOMER_ADDR (object id 6843)
3797 TABLE ACCESS BY INDEX ROWID CUSTOMER
3797 INDEX UNIQUE SCAN XPKCUSTOMER (object id 6635)
100 TABLE ACCESS BY INDEX ROWID CUSTOMER_ADDR
100 BITMAP CONVERSION TO ROWIDS
1 BITMAP OR
1 BITMAP CONVERSION FROM ROWIDS
3797 INDEX RANGE SCAN XIE1CUSTOMER_ADDR (object id 6843)
1 BITMAP CONVERSION FROM ROWIDS
3797 SORT ORDER BY
3797 INDEX RANGE SCAN XIE1CUSTOMER_ADDR (object id 6843)
0 TABLE ACCESS BY INDEX ROWID PHONE
0 INDEX UNIQUE SCAN XPKPHONE (object id 6727)
100 TABLE ACCESS BY INDEX ROWID PHONE
100 INDEX UNIQUE SCAN XPKPHONE (object id 6727)
0 INDEX RANGE SCAN XPKADDITIONAL_ACCOUNT (object id 6609)
BEGIN SP_SEARCH_CUSTOMERS_BASIC(NULL, NULL, NULL, NULL, NULL, NULL, '12309',
:V1, 0); END;
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.01 0.01 0 0 0 1
Fetch 0 0.00 0.00 0 0 0 0
total 2 0.01 0.01 0 0 0 1
Misses in library cache during parse: 1
Optimizer goal: ALL_ROWS
Parsing user id: 21
BEGIN DBMS_APPLICATION_INFO.SET_MODULE(:1,NULL); END;
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 1
Fetch 0 0.00 0.00 0 0 0 0
total 2 0.00 0.00 0 0 0 1
Misses in library cache during parse: 0
Optimizer goal: ALL_ROWS
Parsing user id: 21
SELECT USER
FROM
DUAL
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 3 0 1
total 3 0.00 0.00 0 3 0 1
Misses in library cache during parse: 0
Optimizer goal: ALL_ROWS
Parsing user id: 21
Rows Row Source Operation
1 TABLE ACCESS FULL DUAL
BEGIN DBMS_OUTPUT.DISABLE; END;
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 1
Fetch 0 0.00 0.00 0 0
Similar Messages
-
Hi,
I have a query which fetches around 100 records from a table which has approximately 30 million records. Unfortunately, I have to use the same table and can't go ahead with a new table.
The query executes within a second from RapidSQL. The problem I'm facing is it takes more than 10 minutes when I run it through the Java application. It doesn't throw any exceptions, it executes properly.
The query:
SELECT aaa, bbb, SUM(ccc), SUM(ddd), etc
FROM MyTable
WHERE SomeDate= date_entered_by_user AND SomeString IN ("aaa","bbb")
GROUP BY aaa,bbbI have an existing clustered index on SomeDate and SomeString fields.
To check I replaced the where clause with
WHERE SomeDate= date_entered_by_user AND SomeString = "aaa"No improvements.
What could be the problem?
Thank you,
LoboIt's hard for me to see how a stored proc will address this problem. I don't think it changes anything. Can you explain? The problem is slow query execution time. One way to speed up the execution time inside the RDBMS is to streamline the internal operations inside the interpreter.
When the engine receives a command to execute a SQL statement, it does a few things before actually executing the statement. These things take time. First, it checks to make sure there are no syntax errors in the SQL statement. Second, it checks to make sure all of the tables, columns and relationships "are in order." Third, it formulates an execution plan. This last step takes the most time out of the three. But, they all take time. The speed of these processes may vary from product to product.
When you create a stored procedure in a RDBMS, the processes above occur when you create the procedure. Most importantly, once an execution plan is created it is stored and reused whenever the stored procedure is ran. So, whenever an application calls the stored procedure, the execution plan has already been created. The engine does not have to anaylze the SELECT|INSERT|UPDATE|DELETE statements and create the plan (over and over again).
The stored execution plan will enable the engine to execute the query faster.
/> -
Function and procedure execution
hi all,
i have question in procedure execution and function execution oracle database.
i want know that which is faster in execution procedure or function.
can i see the time taken by procedure and select query
i want to see only time not cpu cost or anything else.
i am waiting for your responses...There is no difference in cost between whether something is a function or a procedure.
The decision making should reflect usage only. For example you can not use a procedure in SQL.
If you wish to break things down further focus on 10046 and 10053 tracing.
Seeing time only is roughly equivalent to cutting off all of your fingers to see how something feels to your thumb.
Timing is only one very small part of what you should be watching. -
Disable text while procedure execution
Hi,
oracle9i
How to disable the below text while procedure execution ?
old 15: Procedure_name(&var1);
new 15: Procedure_name(&var2);
RegardsUse SET VERIFY OFF.
It won't make any difference in the output that you get, but its just for you to see which variable is getting replaced by which value. -
How can i check the procedure execution time..?
Hi All,
Can any one of you tell me how can i check the procedure execution time..?
Thanks in advance.if running it from SQL*Plus,
SQL> set timing on
Or from PL/SQL, use DBMS_UTILITY.GET_TIME before and after the call and calclate the difference. -
File dialog box slow down execution
Dear all,
I am using Labview 8.2.1 with Windows XP.
I have a program who's allow the user to select any file or folder thanks to File dialog box.
For a reason that i don't understand when this dialog box is displayed, other parrallel while loop time execution goes slow down.
Put on my LabView front panel File Path command without any code and press "Browse" file button as shown on joined picture_1 birng slow down execution of the while loop.
Does any body could explain why this problem appear ?
By switch off on LabView Tool parameter "Use native file dialogs" (picture_2). the problem disapear. Unfortunately this kind of old dialog box is not practical...
If any body have an idea it could help me.
Thanks.
Solved!
Go to Solution.
Attachments:
picture_1.JPG 16 KB
picture_2.JPG 71 KB__KB__ wrote:
Hello,
When the File dialog box is running, other while loop time execution goes down.
Thanks.
This you have already mentioned in your first post... now my question is how you've actually figured it out... or can you share your code here???
I am not allergic to Kudos, in fact I love Kudos.
Make your LabVIEW experience more CONVENIENT. -
Please help me how to maintain log for procedure execution
Hi Experts,
How to maintain the log for procedure execution
I want to maintain the log for procedures as below.
Once the procedure starts it should show status as RUNNING and PROC_END_TIME should be NULL.
Once the procedure completes it should show status as COMPLETED and shold show the PROC_END_TIME.
Once the MAIN_PROC completes then only the status of that procedure should show COMPLETED.
STEP_ID RECORDS_INS_UPD RECORDS_DELETED PROC_NAME PROC_START_TIME PROC_END_TIME JOB_STATUS ERROR_MSG
1 500 0 MAIN_PROC 1/4/2014 5:47:38.000000 AM RUNNING
2 100 0 SUB_PROC1 1/4/2014 5:49:30.000000 AM RUNNING
3 0 0 SUB_PROC2 1/4/2014 5:47:38.000000 AM 1/4/2014 5:47:38.000000 AM COMPLETED
I have tried the below code but it's not working properly.
CREATE OR REPLACE PROCEDURE procedures_log
p_seq NUMBER,
p_rec_ins_upd NUMBER,
p_rec_deleted NUMBER,
p_proc_name VARCHAR2,
p_start_time TIMESTAMP,
p_end_time TIMESTAMP,
p_job_status VARCHAR2,
p_error_msg VARCHAR2
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF p_seq = 0 THEN
INSERT INTO proc_log
STEP_ID,
ORG_ID,
TABLENAME,
RECORDS_INS_UPD,
RECORDS_DELETED,
JOB_NAME,
PROC_NAME,
JOB_START_TIME,
JOB_END_TIME,
JOB_STATUS,
ERROR_MSG
VALUES
p_seq,
p_rec_ins_upd,
p_rec_deleted,
p_proc_name,
p_start_time,
p_end_time,
p_job_status,
p_error_msg
ELSE
UPDATE proc_log
SET
RECORDS_INS_UPD = p_rec_ins_upd,
RECORDS_DELETED = p_rec_deleted,
JOB_END_TIME = p_end_time,
JOB_STATUS = p_job_status,
STEP_ID = p_seq,
ERROR_MSG = p_error_msg
WHERE UPPER(TRIM(PROC_NAME)) = UPPER(TRIM(p_proc_name))
AND STEP_ID = 0
AND JOB_STATUS = 'RUNNING';
END IF;
COMMIT;
EXCEPTION
WHEN OTHERS
THEN NULL;
END;
Please help me.
Thanks.ramya_162 wrote:
Hi,
I don't want to maintain multiple records for one procedure.
The log table will grow huge.
Please help me.
Thanks.
You have two options.
Either a running log, from which you periodically delete old records, or maintain a standing record for each process you are tracking.
Ok, let's take the second, since that seems to be your preferred method.
Going back to your original post, you gave us code and said "I have tried the below code but it's not working properly."
Please define "not working". That statement is totally devoid of actionable or diagnostic information. -
Pricing procedure execution...
Hi Folks,
How SAP reads the pricing procedure..
Example
Con.Type Requirement Routine
ZSAA 601 901
ZSAB 602 902
Doubt 1: -Is system reads this pricing procedure line by line or coulmn by column?, In the debug we noticed it goes column by colmun? why?
Doubt 2: - I want to know the value found for ZSAA during the execution of 602 requirement. Example scenario is if ZSAA is more than 100$ don't execute ZSAB.Pricing Procedure:
Determination of Pricing Procedure:
In SD, Pricing Procedure is determined based on Sales Area (Sales Organization + Distribution Centre + Division) + Customer Pricing Procedure + Document Pricing Procedure through T.Code: OVKK. Sales Area is determined in Sales Order Header Level. Customer Pricing Procedure is determined from Customer Master. Document Pricing Procedure is determined from Sales Document Type / Billing Type (if configured). Once the pricing procedure is determined, Condition records are fetched. If appropriate condition records are found, the price is determined. If Mandatory pricing condition is missing, system will through an error message.
Configuration of Pricing Procedure:
Step 1:
Condition table (T.Code: V/04): If existing condition table meets the requirement, we need not create a new condition table. Considering the requirement for new condition table, the configuration will be done in spro as follows: IMG --> Sales & Distribution --> Basic Function --> Pricing Control --> Condition Table (select the required fields combination, which will store condition record).
Step 2:
Access Sequence (T.Code: V/07): If existing access sequence meets the requirement, we need not create a new access sequence. Considering the requirement for new sequence, the configuration will be done in spro as follows: IMG --> Sales & Distribution --> Basic Function --> Pricing Control --> Access Sequence (Access sequence is made up of Accesses (Tables) & the order of priority in which it is to be accessed. Here we assign the condition table to access sequence.
Step 3:
Condition Type (T.Code: V/06): If existing condition type meets the requirement, we need not create a new condition type. Considering the requirement for new condition type, the configuration will be done in spro as follows: IMG --> Sales & Distribution --> Basic Function --> Pricing Control --> Condition Type. It is always recommended to copy an existing similar condition type & make the neccessary changes. Here we assign Access sequence to Condition type.
Step 4:
a. Pricing Procedure (T.Code: V/08): It is recommended to copy a similar pricing procedure & make the neccesary changes in new pricing procedure. Pricing Procedure is a set of condition type & arranged in the sequence in which it has to perform the calculation. Considering the requirement for new Pricing Procedure, the configuration will be done in spro as follows: IMG --> Sales & Distribution --> Basic Function --> Pricing Control --> Pricing Procedure --> Maintain Pricing Procedure.
b. Pricing Procedure (T.Code: VOK0): After maintaining the pricing procedure the next step will be determination of pricing procedure. Configuration for determining pricing procedure in SPRO is as follows: IMG --> Sales & Distribution --> Basic Function --> Pricing Control --> Pricing Procedure --> Determine Pricing Procedure.
5. Condition record (T.Code: VK11 / VK12): Condition record is a master data, which is required to be maintained by Core team / person responsible from the client. During new implementation, the condition records can be uploaded using tools like SCAT, LSMW, etc. Condition Record is maintained in T.Code: VK11 / VK12, which are captured in Sales Order & Billing.
Also check document pricing procedure in Sales Document Type (T.Code: VOV8 - Sales order Type, VOFA: Billing Type (If Required)), customer pricing procedure in Customer Master Data (T.Code: XD02), ... are in place.
Regards,
Rajesh Banka
Reward suitable points. -
Procedure execution time difference in Oacle 9i and Oracle 10g
Hi,
My procedure is taking time on
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 is 14 min.
same procedure is taking time on oracle Release 9.2.0.1.0 is 1 min.
1) Data is same in both environment.
2) Number of records are same 485 rows for cursor select statement.
3)Please guide me how to reduce the time in oracle 10g for procedure?
i have checked the explain plan for that cursor query it is different in both enviroment.
so i have analysis that procedure is taking time on cursor fetch into statement in oracle 10g.
example:-
create or replace procedure myproc
CURSOR cur_list
IS select num
from tbl
where exist(select.......
EXECUTE IMMEDIATE 'ALTER SESSION SET SQL_TRACE = TRUE';
EXECUTE IMMEDIATE 'ALTER SESSION SET TIMED_STATISTICS = TRUE';
OPEN cur_list;
LOOP
FETCH cur_list INTO cur_list; -----My procedure is taking time in this statement only for some list number. there are 485 list number.
end loop;
TRACE file for oracle 10g is look like this:-
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.37 0.46 0 2 0 0
Fetch 486 747.07 730.14 1340 56500700 0 485
total 488 747.45 730.60 1340 56500702 0 485
ORACLE 9i EXPLAIN PLAN FOR cursor query:-
Plan
SELECT STATEMENT CHOOSECost: 2 Bytes: 144 Cardinality: 12
18 INDEX RANGE SCAN UNIQUE LISL.LISL_LIST_PK Cost: 2 Bytes: 144 Cardinality: 12
17 UNION-ALL
2 FILTER
1 TABLE ACCESS FULL SLD.P Cost: 12 Bytes: 36 Cardinality: 1
16 NESTED LOOPS Cost: 171 Bytes: 141 Cardinality: 1
11 NESTED LOOPS Cost: 169 Bytes: 94 Cardinality: 1
8 NESTED LOOPS Cost: 168 Bytes: 78 Cardinality: 1
6 NESTED LOOPS Cost: 168 Bytes: 62 Cardinality: 1
4 TABLE ACCESS BY INDEX ROWID SLD.L Cost: 168 Bytes: 49 Cardinality: 1
3 INDEX RANGE SCAN UNIQUE SLD.PK_L Cost: 162 Cardinality: 9
5 INDEX UNIQUE SCAN UNIQUE SLD.SYS_C0025717 Bytes: 45,760 Cardinality: 3,520
7 INDEX UNIQUE SCAN UNIQUE SLD.PRP Bytes: 63,904 Cardinality: 3,994
10 TABLE ACCESS BY INDEX ROWID SLD.P Cost: 1 Bytes: 10,480 Cardinality: 655
9 INDEX UNIQUE SCAN UNIQUE SLD.PK_P Cardinality: 9
15 TABLE ACCESS BY INDEX ROWID SLD.GRP_E Cost: 2 Bytes: 9,447 Cardinality: 201
14 INDEX UNIQUE SCAN UNIQUE SLD.PRP_E Cost: 1 Cardinality: 29
13 TABLE ACCESS BY INDEX ROWID SLD.E Cost: 2 Bytes: 16 Cardinality: 1
12 INDEX UNIQUE SCAN UNIQUE SLD.SYS_C0025717 Cost: 1 Cardinality: 14,078
ORACLE 10G EXPLAIN PLAN FOR cursor query:-
SELECT STATEMENT ALL_ROWSCost: 206,103 Bytes: 12 Cardinality: 1
18 FILTER
1 INDEX FAST FULL SCAN INDEX (UNIQUE) LISL.LISL_LIST_PK Cost: 2 Bytes: 8,232 Cardinality: 686
17 UNION-ALL
3 FILTER
2 TABLE ACCESS FULL TABLE SLD.P Cost: 26 Bytes: 72 Cardinality: 2
16 NESTED LOOPS Cost: 574 Bytes: 157 Cardinality: 1
14 NESTED LOOPS Cost: 574 Bytes: 141 Cardinality: 1
12 NESTED LOOPS Cost: 574 Bytes: 128 Cardinality: 1
9 NESTED LOOPS Cost: 573 Bytes: 112 Cardinality: 1
6 HASH JOIN RIGHT SEMI Cost: 563 Bytes: 315 Cardinality: 5
4 TABLE ACCESS FULL TABLE SLD.E Cost: 80 Bytes: 223,120 Cardinality: 13,945
5 TABLE ACCESS FULL TABLE SLD.GRP_E Cost: 481 Bytes: 3,238,582 Cardinality: 68,906
8 TABLE ACCESS BY INDEX ROWID TABLE SLD.L Cost: 2 Bytes: 49 Cardinality: 1
7 INDEX UNIQUE SCAN INDEX (UNIQUE) SLD.PK_L Cost: 1 Cardinality: 1
11 TABLE ACCESS BY INDEX ROWID TABLE SLD.P Cost: 1 Bytes: 16 Cardinality: 1
10 INDEX UNIQUE SCAN INDEX (UNIQUE) SLD.PK_P Cost: 0 Cardinality: 1
13 INDEX UNIQUE SCAN INDEX (UNIQUE) SLD.SYS_C0011870 Cost: 0 Bytes: 13 Cardinality: 1
15 INDEX UNIQUE SCAN INDEX (UNIQUE) SLD.PRP Cost: 0 Bytes: 16 Cardinality: 1
so Please guide me how to reduce the time in oracle 10g for procedure?
1) Is this envrionment setting parameter?
2) I have to tune the query? but which is executing fine on oracle 9i?
so how to decrease the execution time?
Thanks in advance.SELECT l_nr
FROM x.ls b
WHERE b.cd = '01'
AND b.co_code = '001'
AND EXISTS (
SELECT T_L
FROM g.C
WHERE C_cd = '01'
AND C_co_code = '001'
AND C_flg = 'A'
AND C_eff_dt <= sysdate
AND C_end_dt >=
sysdate
AND C_type_code <> 1
AND C_type_code <> 1
AND targt_ls_type = 'C'
AND T_L <> 9999
AND T_L = b.l_nr
UNION ALL
SELECT l.T_L
FROM g.C C,
g.ep_e B,
g.ep ep,
g.e A,
g.lk_in l
WHERE l.cd = '01'
AND l.co_code = '001'
AND l.cd = C.C_cd
AND l.co_code = C.C_co_code
AND l.C_nbr = C.C_nbr
AND l.targt_ls_type = 'C'
AND lk_in_eff_dt <=
sysdate
AND lk_in_end_dt >=
( sysdate
+ 1
AND ( (logic_delte_flg = '0')
OR ( logic_delte_flg IN ('1', '3')
AND lk_in_eff_dt <> lk_in_end_dt
AND l.cd = ep.C_cd
AND l.co_code = ep.C_co_code
AND l.C_nbr = ep.C_nbr
AND l.ep_nbr = ep.ep_nbr
AND l.cd = A.e_cd
AND l.co_code = A.e_co_code
AND l.e_nbr = A.e_nbr
AND l.cd = B.cd
AND l.co_code = B.co_code
AND l.C_nbr = B.C_nbr
AND l.ep_nbr = B.ep_nbr
AND l.e_nbr = B.e_nbr
AND l.ep_e_rev_nbr = B.ep_e_rev_nbr
AND B.flg = 'A'
AND EXISTS (
SELECT A.e_nbr
FROM g.e A
WHERE A.e_cd = B.cd
AND A.e_co_code = B.co_code
AND A.e_nbr = B.e_nbr
AND A.e_type_code ^= 8)
AND C_type_code <> 10
AND C.C_type_code <> 13
AND l.T_L = b.l_nr)
--yes index is same -
How to know child procedure Execution time with in parent procedure
Hi Team,
I've a requirement in which I need to get the execution time of a child procedure while its running in a parent procedure in PLSQL. While the child process is running, I want to know its execution time so that if it execution time exceeds more than 5 seconds than I want to through an error. Please let me know by what means this can be achieved in plsql.
Regards,
Tech D.TechD wrote:
Hi Team,
I've a requirement in which I need to get the execution time of a child procedure while its running in a parent procedure in PLSQL. While the child process is running, I want to know its execution time so that if it execution time exceeds more than 5 seconds than I want to through an error. Please let me know by what means this can be achieved in plsql.
Regards,
Tech D.PL/SQL is NOT a Real Time programming language.
The procedure that invokes the child procedure is effectively dormant while the child runs.
Plus there is no easy way to know when 5 seconds has elapsed. -
Measure procedure execution time..
Hi,
Is there any possibility to measure how long each of a procedure in database take?? Is that possible for Oracle's V$ views or by performance report like AWR? On the other hand, is that possible to measure execution time for SQL statements, but without using "set timing on".
Best,
tutusThis is just an add-on to Satish's reply. You may want to chck this link to see how Profiler works,
http://www.oracle-base.com/articles/9i/DBMS_PROFILER.php
HTH
Aman.... -
Slow PowerShell execution of Microsoft Exchange 2013 commands from c#
I have the following code that executes an exchange cmdlet. It works fast with command that return some output but work slow if command has no output.
for example
Invoke("Get-Mailbox")
prints following output:
Begin execution at 11:44:43
Finish execution at 11:44:51
Output :
Administrator
Discovery Search Mailbox
Artem Romanchik
Execution time was about 8 second(6 second for loading exchange snappin + 2 seconds for command execution)
Slow example is
Invoke("Set-Mailbox -identity tema -MaxSendSize 10MB")
Begin execution at 11:53:34
Finish execution at 11:54:36
Output :
Now it was 62 seconds(2 seconds for command and 60 seconds of waiting for something)
How can I reduce execution time of second example?
Invoke method code:
public void Invoke(string command)
var config = RunspaceConfiguration.Create();
PSSnapInException warning;
config.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Snapin", out warning);
using(var runspace = RunspaceFactory.CreateRunspace(config))
runspace.Open();
using(var _psInstance = new RunspaceInvoke(runspace))
var psCommand = new PSCommand();
Console.WriteLine(String.Format("Begin execution at {0}", DateTime.Now.ToLongTimeString()));
var result = _psInstance.Invoke(command);
Console.WriteLine(String.Format("Finish execution at {0}", DateTime.Now.ToLongTimeString()));
var output = "";
foreach (var line in result)
if (line == null)
continue;
output += "\n" + line.BaseObject.ToString();
Console.WriteLine(String.Format("Output: {0}", output));
runspace.Close();On 2010 and 2013 Powershell is throttled
http://technet.microsoft.com/en-us/library/dd298094(v=exchg.150).aspxyou might want to do some testing with a user that has throttling policy disabled. Also you might want to check the logs on the CAS server the request are going through eg \Microsoft\Exchange
Server\V15\Logging\CmdletInfra you should be able to determine from these if your being throttled.
Cheers
Glen -
Recurring Doc Posting Procedure & Execution
Hi Experts,
Kindly inform the Procedure for Recurring Doc Posting & Execution ( Is helpful in real time)
Thk & Reg
VasuHi,
There are following steps for recurring entry posting
1. Create Recurring Document in FBD1 and can display document in FBD3
2. Create Posting documents from recurring document F.14
3. Run Batch input session in SM35
You can see accounting document in log.
if helpful, Please assign points.
For any query Please let me know.
Regards
Pawan Gupta -
Resume procedure execution after Exception Handler
Hi -- Can anyone tell me how to resume execution of my procedure if and when I fall into the Exception Handler?
I'm in a for/loop and i want to move to the next record after falling into the exception handler.
Thanks,
~ChristineIt's just a scoping issue...
BEGIN
FOR r IN ( SELECT ... FROM whatever ) LOOP
BEGIN
-- do stuff
EXCEPTION
WHEN others THEN
log_error(SQLERRM);
END;
END LOOP;
END;
/If you're using BULK processing you may want to check out %BULK_EXCEPTIONS.
Cheers, APC -
Why is job always slow in execution ?
can somebody tell what powershell commandlet "stop-scdwjob" exactly does. does it pause the execution of job at a module or uses check pointing of workflows so that execution is resumed always from the last step.
2ndly the environment of execution of workflows is very nice, but why are these jobs unnecessarily slow. Is it restricted at some CPU threshold or disk ? because i always notice these ETL jobs to continue to run for very long before completing. Even
though during the course the execution neither CPU or disk is high in utilization ????
Can somebody help shed light on this internals WF environment of Service Manager 2012 R2, please.
Shahid RoofiTake a look at the variety of answers to similar questions in More Like This >>>>
to the right of your question (plus others within those threads). It appears quite a common problem with little in the way of explanation.
Maybe you are looking for
-
HP LaserJet - network printer problem FIXED
Hi, I'm aware this may not work for all, but I've sorted my own problems, which I suspect are common to many who still have a really solid HP (or other) network printer that was no longer available since Snow Leopard did away with Apple Talk. The ans
-
I'm travelling and trying to back up my new iPhone to iCloud. I have sufficient storage, am connected to wifi and it's plugged into a power source and yet it doesn't seem to work at all. I'm currently in India. Could that be the cause or can anyone s
-
When will come the new IPod Touch (5G)?
See the question above. Because I want to buy an IPod Touch but they say, that there will be one in a few months and so I want to have the latest.
-
Cs5 compatible laptop video cards with hardware acceleration
Is there a list or does anyone know of laptops with compatible video cards for cs5 hardware acceleration? This would be for a windows 7 64bit system.' Thanks!
-
USING PHOTOSHOP ELEMENTS 9 WITH WINDOWS 7 CURSUR ISSUE
USING PHOTOSHOP ELEMENTS 9 WITH WINDOWS 7 I HAVE THREE SMALL BOXES FOR A CURSOR IN PLACE OF A SMALL ARROW. HOW CAN I CORRECT THIS ISSUE. I HAVE LOADED THE TWO PATCH FILES THAT ARE NOT RAW FILE RELATED BUT I STILL HAVE THE ISSUE.