One of the most frequently used function modules in custom code in the 1Order area is CRM_ORDER_READ. Often we see performance problems because of the time spent in this function module. Since the function module is a well-known function module from SAP it is not clear what to do.
One context where CRM_ORDER_READ calls are seen are searches. In this context CRM_ORDER_READ is not the right function module to use altogether. The reason is that there is a considerable overhead inside CRM_ORDER_READ by filling the object buffer and database buffer. Technically these are some global tables inside the 1Order function groups. In the context of searches this time is wasted because every search is different and the search result should always reflect the current database status. So as a general avoid the usage of CRM_ORDER_READ in searches.
You will also see calls of CRM_ORDER_READ inside 1Order BADIs such as BADI ORDER_SAVE or 1Order custom event handler callback. In these cases one cannot really say that the usage of CRM_ORDER_READ is wrong. But from a performance point of view there are better options available especially if CRM_ORDER_READ is called many times as it will be explained below.
One thing which is important is that in case you use CRM_ORDER_READ you should use it in the most optimal way. By default CRM_ORDER_READ will do an authority check if the user is allowed to see the data. In many cases the CRM_ORDER_READ call is just for internal purposes and not for data presented to the user. So in this case an authority check is not needed or even wrong. In these cases you can set parameter IV_NO_AUTH_CHECK to bypass the authority check. Another thing is that table IT_REQUESTED_OBJECTS should always be filled with the data you need. Otherwise this information has to be calculated by the return parameters which are requested from CRM_ORDER_READ which again costs time. An even more hidden and unexpected problem of CRM_ORDER_READ is the following: Even if you purely read header information with CRM_ORDER_READ it will internally read all items. Take for instance the following CRM_ORDER_READ call:
lv_object_name = 'ORDERADM_H'.
insert lv_object_name into table lt_object_name.
CALL FUNCTION 'CRM_ORDER_READ'
IT_HEADER_GUID = lt_header_guid
IT_REQUESTED_OBJECTS = lt_object_name
IV_NO_AUTH_CHECK = 'X'
* IV_ONLY_SPEC_ITEMS =
ET_ORDERADM_H = lt_orderadm_h
OTHERS = 1.
You can fix this by setting parameter IV_ONLY_SPEC_ITEMS to ‘X’ when you call CRM_ORDER_READ. Maybe in the future this will also be changed by standard because by parameter IT_REQUESTED_OBJECTS the caller already defined that he wants to read only header information. But for the moment you should set this parameter when you read only header information. The bigger orders you deal with the bigger is the effect.
Even if you consider all of this the API CRM_ORDER_READ will have a certain performance overhead for managing table IT_REQUESTED_OBJECTS etc. Of course the effect will strongly depend on the number of CRM_ORDER_READ calls which are executed. So if you look for the best performance it is always better to use the direct object read such as CRM_ORDERADM_H_READ_OB, CRM_ORDERADM_I_READ_OB, CRM_SCHEDLIN_READ_OB and so on. (The right function module to use for a particular 1Order object can be found inside CRM_ORDER_READ_OW in forms read_header_ext, read_header_sets, read_item_ext and read_item_sets.) To get a rough idea how big the effect is, 1000 calls of CRM_ORDER_READ were compared with 1000 calls of CRM_ORDERADM_H_READ_OB.
You can see that the there is a roughly factor of 20 difference in runtime. While a call of CRM_ORDERADM_H_READ_OB took only 50 microseconds on average, a call of CRM_ORDER_READ to read the same data takes around 1 millisecond. Once again, this data will heavily depend on things like hardware, database size etc. and are just meant as a rough orientation.